简体   繁体   中英

JUnit testing transactional methods

I am new to JUnit and trying to test a spring web service which uses JPA DAOs. I need to test a service method similar to below.

Service method is annotated with @Transactional(propagation=Propagation.REQUIRED) and ServiceObjectRepository.update() method calls a native 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 runs and rollback the db transactions. But the problem is when I read the updatedServiceObject after calling the serviceMethod it does not return the updated object. So my test fails with a NullPointerException at the assertEquals . Any idea to overcome this issue?

Finally I came up with a solution, Rather than creating ServiceObject and saving to DB in the test method, I have done it before the test method and deletion of the created objects done after the transaction. So that 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 test method or test class does not necessary to be transactional in such a case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM