JUnit 测试事务方法

Thu*_*lla 5 java junit spring transactional

我是 JUnit 新手,正在尝试测试使用 JPA DAO 的 Spring Web 服务。我需要测试类似于下面的服务方法。

服务方法使用注释@Transactional(propagation=Propagation.REQUIRED)ServiceObjectRepository.update()方法调用本机 sql 查询来更新数据库。

@Transactional(propagation=Propagation.REQUIRED)    
public void serviceMethod(){
        //Read DB for ServiceObject to update
        //Call  ServiceObjectRepository.update() method to update DB
}
Run Code Online (Sandbox Code Playgroud)

服务对象存储库

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);    
}
Run Code Online (Sandbox Code Playgroud)

测试类

@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);

   }
}
Run Code Online (Sandbox Code Playgroud)

我的测试运行并回滚数据库事务。但问题是,当我在updatedServiceObject调用后读取它时serviceMethod,它不会返回更新的对象。所以我的测试失败,并在assertEquals. 有什么想法可以克服这个问题吗?

Thu*_*lla 4

最后我想出了一个解决方案,ServiceObject我不是在测试方法中创建并保存到数据库,而是在测试方法之前完成并在事务之后删除创建的对象。所以我的测试课看起来像,

@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
    }
}
Run Code Online (Sandbox Code Playgroud)

我发现在这种情况下测试方法或测试类不一定是事务性的。