JUnit transaction methods
I am new to JUnit and am trying to test spring webservice that uses JPA DAO. I need to test a maintenance method similar to the one below.
The service method is annotated with the method @Transactional(propagation=Propagation.REQUIRED)
and ServiceObjectRepository.update()
calls its own sql query to update the db.
@Transactional(propagation=Propagation.REQUIRED)
public void serviceMethod(){
//Read DB for ServiceObject to update
//Call ServiceObjectRepository.update() method to update DB
}
ServiceObjectRepository
public interface ServiceObjectRepository extends JpaRepository<ServiceObject, Integer> {
@Query(value ="UPDATE serviceobjcet AS c SET c.objectstatus= :os WHERE c.objid = :oi", nativeQuery = true)
public Integer update(@Param("os")short objStatus,@Param("oi")int objId);
}
TestClass
@TransactionConfiguration(defaultRollback=true)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(
locations = "classpath:service-test.xml")
@Transactional
public class ServiceHandlerTest {
@Test
public void testServiceMethod() {
//Create ServiceObject and save to DB
//Call serviceMethod()
//Read DB for updatedServiceObject
assertEquals("Test: Object should be in updated state", new Short(3), updatedServiceObject.getObjectstatus(), 0);
}
}
My test passes and rolls back db transactions. But the problem is that when I read updatedServiceObject
after the call serviceMethod
, it doesn't return the updated object. So my test failed with a NullPointerException in assertEquals
. Any idea to resolve this issue?
source to share
Finally I came up with a solution, instead of creating ServiceObject
and saving to DB in the test method, I did it before the test method and deleting the created objects executed after the transaction. So my test class looks like,
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:service-test.xml")
public class ServiceHandlerTest {
@Before
public void setup() {
//Create ServiceObject and save to DB
}
@Test
public void testServiceMethod() {
//Call serviceMethod()
//Read DB for updatedServiceObject
assertEquals("Test: Object should be in updated state", new Short(3), updatedServiceObject.getObjectstatus(), 0);
}
@After
public void teardown() {
//Delete created ServiceObject from DB
}
}
And I found that a test method or test class does not have to be transactional in this case.
source to share