Spring 如何测试@transactional方法

Spring 如何测试@transactional方法,spring,jpa,transactions,Spring,Jpa,Transactions,我有一个spring应用程序,它需要事务。 如何编写测试以查看@Transactional注释是否正常工作? 我有一个带有自动连接repo的服务类,以及类似 @Transactional(propagation = Propagation.REQUIRED) public boolean saveObjectToDb(Object a){ repo.save(a) } 这是你能做的。这不一定是最好的主意,但这里有: @Test public void testTransacti

我有一个spring应用程序,它需要事务。 如何编写测试以查看@Transactional注释是否正常工作? 我有一个带有自动连接repo的服务类,以及类似

@Transactional(propagation = Propagation.REQUIRED)
 public boolean saveObjectToDb(Object a){
 repo.save(a)   

}
这是你能做的。这不一定是最好的主意,但这里有:

 @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();
 }
@测试
公共无效测试事务性(){
Method[]methods=yourClassWhateVeritScaled.class.getMethods();
可选findFirst=Arrays.stream(方法)
.filter(方法->方法.getName()
.equals(“saveObjectToDb”))
.findFirst();
事务[]注释ByType=
findFirst.get().getAnnotationsByType(Transactional.class);
assertThat(annotationsByType).isNotEmpty();
}
因此,我在这里使用的具体断言肯定更切题。然而

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

如果您想测试数据是否真的保存到数据库中,那就更难了。方法包括:

  • 实际上有一个测试数据库,您可以对它运行这些类型的测试。调试这些测试可能很糟糕,但有时它们至少很快,因为在测试开始之前数据库已经启动并运行了
  • 为此类测试旋转内存中的数据库,并针对这些测试执行事务性插入、更新和删除。这也可能是一种痛苦,因为它需要大量的测试工具,而且测试速度很慢。但是,如果它们编写得很好(您不希望JUnit测试类中的一个测试中的数据在开发人员没有意识到的情况下最终出现在另一个测试中),那么它可以是超级可维护的。相对来说
我很想在这里学习更多的方法,但总的来说,这是一个很难正确理解的领域


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

你可以编写自己的单元测试类。这是显而易见的答案,我应该更好地定义这个问题,我想。。。无论如何,我的问题是我有一个只做一件事的方法,我不知道如何在测试中中断它,看看事务性注释是否有效。谢谢你的回答。测试是检查事务性注释的一种非常好的方法。但是,我必须证明,如果其中一个DB写入失败,我的事务将回滚。我做了一个测试,调用了更多的写操作,并强制在调用之间进行中断。这是一个有点“黑客”,我相信这不是最好的方式,但它做的工作!