JUnit测试总是回滚事务

时间:2012-03-22 06:21:13

标签: java spring junit4

我正在运行一个简单的JUnit测试再次应用程序DAO。问题是我总是得到:

javax.persistence.RollbackException: Transaction marked as rollbackOnly

JUnit测试是:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:com/my/app/context.xml"}
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = false)
@Transactional
public class PerformanceTest {

    @Test
    @Transactional(propagation= Propagation.REQUIRES_NEW)
    @Rollback(false)
    public void testMsisdnCreationPerformance() {
        // Create a JPA entity

        // Persist JPA entity
    }
}

正如您所看到的,我明确表示不会回滚此方法。

Spring JUnit是否支持始终将回滚设置为true?

提前致谢,

7 个答案:

答案 0 :(得分:47)

它应该像您期望的那样工作,但可能是您在测试中的类中打开另一个事务,或者您在其他地方有其他功能/或错误。

顺便说一下,这个注释应该是有用的:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:com/my/app/context.xml"}
@Transactional
public class PerformanceTest {

    @Test
    @Rollback(false)
    public void testMsisdnCreationPerformance() {
        // Create a JPA entity

        // Persist JPA entity
    }
}

@See Spring Reference Chapter 9.3.5.4 Transaction management

答案 1 :(得分:11)

希望更改数据库并保留修改的测试很奇怪。 测试应该是正交的:没有测试取决于另一个。 此外,测试应该独立于测试顺序,甚至是idempotent

因此,要么想要在setUp()方法中更改数据库并回滚tearDown()方法中的更改,要么设置一个测试数据库,其中包含一些测试数据库中的值。

也许我在这里遗漏了一些东西,但通常你不应该这样想。

答案 2 :(得分:10)

只需添加注释回滚并将标志设置为false。

   @Test
   @Rollback(false)

答案 3 :(得分:3)

来自官方文档:

  

默认情况下,测试事务将在之后自动回滚   完成测试;但是,事务提交和回滚   可以通过@Commit和@Rollback以声明方式配置行为   注释

https://docs.spring.io/spring/docs/current/spring-framework-reference/html/integration-testing.html#integration-testing-annotations

  

@Commit表示事务测试方法的事务   应该在测试方法完成后提交。 @Commit可以   用作@Rollback(false)的直接替代品以便更多   明确传达代码的意图。

答案 4 :(得分:0)

我同意拉尔夫的回答。

Propagation.REQUIRES_NEW 会创建一个新事务,这可能与运行测试的主要事务路由不匹配。

根据我的简单经验,注释 @Transactional 将正确地用于定义每个测试应该运行的事务上下文,将特定的当前Rollback子句委托给此一个(如Ralph所示)。

拉尔夫的答案很有用,同时Snicolas的答案涉及管理测试环境的特定情况。 idempotence 是集成和自动测试的基础,但应该是实现它们的不同方法。 问题是,你有哪种方法?那些方法有什么样的行为?

   [...]
   @Transactional

   public class Test {

   @Test
   @Rollback(false)
   public void test() {

   [...]

简单,问题一致的方式:)

答案 5 :(得分:0)

I use Junit5, both commit and rollback(false) works with me.

    @ExtendWith(SpringExtension.class)
    @SpringBootTest
    @Transactional
    public class MyIntegrationTest {

      @Test
      @DisplayName("Spring Boot Will Rollback Data, " +
      "Can Disable it By Add @Commit Or @Rollback(false) Annotation")
      //@Commit
      //@Rollback(false)
      public void test() throws Exception {
       //your test codes here...
      }

答案 6 :(得分:0)

  1. 在测试课程级别上添加@Rollback

  2. 在测试方法上添加@Transactional(value = "your_ManagerName",rollbackFor = Exception.class)