如何测试@transactional方法

时间:2017-07-13 15:40:05

标签: spring jpa transactions

我有一个spring应用程序,它需要事务处理。 我如何编写测试以查看@Transactional注释是否正常工作? 我有一个带有自动回购仓库的服务类,以及像

这样的方法
@Transactional(propagation = Propagation.REQUIRED)
 public boolean saveObjectToDb(Object a){
 repo.save(a)   

}

1 个答案:

答案 0 :(得分:0)

这是可以做的事情。这不一定是最好的主意,但这里有:

 @Test
 public void testTransactionality() {
   Method[] methods = YourClassWhateverItsCalled.class.getMethods();
   Optional<Method> findFirst = Arrays.stream(methods)
      .filter(method -> method.getName()
      .equals("saveObjectToDb"))
      .findFirst();

   Transactional[] annotationsByType = 
      findFirst.get().getAnnotationsByType(Transactional.class);

   assertThat(annotationsByType).isNotEmpty();
 }

因此,我在这里使用的具体断言可以更加明确。然而...

这不是最好的想法的原因是因为你只是测试注释是否存在。您不测试事实是否实际保存到数据库中。在开发环境中手动测试内容有其优点,您应该记住,您不需要测试100%的代码。 80%是一个很好的经验法则。

如果你想测试数据实际上是保存到数据库那么难。方法包括:

  • 实际上有一个测试数据库可以运行这些类型的测试。调试这些测试可能很糟糕,但有时它们至少很快,因为数据库在测试出现之前已经启动并运行。
  • 为每种此类测试启动内存数据库,并对 执行事务性插入,更新和删除。这也可能是一种痛苦,因为它在测试工具方面需要很多并且测试很慢。但是,如果它们编写得很好(您不希望JUnit测试类中的一个测试中的数据在没有开发人员意识的情况下最终在另一个测试中结束),那么它可以是超级可维护的。相对而言。

我希望在这里了解更多方法,但总的来说这是一个难以解决的问题。

更新:我应该注意,如果您测试数据库访问,请务必保持测试单元测试。没有什么比试图弄清楚跨越20个不同类的数据库访问测试所发生的事情更糟糕的了。纯。地狱。