2012-03-22 90 views
16

我正在运行一个简单的JUnit测试来重新应用DAO。问题是,我总是得到:JUnit测试总是回滚事务

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?

由于提前,

+0

你在哪里得到例外?你能发布堆栈跟踪吗? – nwinkler 2012-03-22 07:06:18

回答

10

奇怪的是希望有一个测试,改变你的数据库,并保留修改。 测试应该是正交的:没有测试依赖于其他测试。 此外,测试应该是独立的测试订单,甚至idempotent

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

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

+23

但这不是问题。 – Ralph 2012-03-22 07:07:20

+7

@Ralph但它仍然是正确的答案。 – 2012-03-22 07:21:47

+6

我有一个非常好的理由,为什么不回滚junit测试。那么“正确答案”并不是你不应该这样做。正确的答案是能解释如何的人。 – user829237 2012-12-11 12:04:22

39

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

顺便说一下这个注释应该是enougth:

@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

+1在字面意义上提供正确的答案,但我更喜欢其他答案 – 2012-03-22 07:22:41

0

我同意拉尔夫的答案。

Propagation.REQUIRES_NEW创建一个新的交易,这可能不会在测试运行的主要交易途径相匹配。

在我的简单体验注解@Transactional将正常工作,以确定在每一个测试应该运行事务上下文,委托给这一个特定电流回滚条款(由Ralph如图所示)。

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

[...] 
    @Transactional 

    public class Test { 

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

    [...] 

是简单的,问题相干方式:)

6

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

@Test 
    @Rollback(false) 
1

来自官方的文档:

默认情况下,测试数据将被自动 完成测试后回滚;然而,事务提交和回滚 行为可以通过@Commit和@Rollback 注解

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

@Commit表明,对于一个事务测试方法 事务应该之后被提交测试方法已完成。 @Commit可以使用 作为@Rollback(false)的直接替换,以便更多 明确传达代码的意图。

+0

对我来说非常困惑的是,即使异常一直向上冒泡,测试也会提交txn,正常情况下(@Transactional on business类而不是测试方法),这会触发txn回滚。 – 2017-09-01 15:47:30

+0

仅适用于选中的例外情况。未检查将回滚自动贩卖机。 https://stackoverflow.com/questions/3701376/rollback-on-every-checked-exception-whenever-i-say-transactional – harryssuperman 2017-10-27 14:41:54