2012-03-22 26 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

答えて

10

あなたのデータベースを変更し、変更を保つテストを希望する奇妙です。 テストは直交していると想定されます。テストは他のテストに依存しません。 さらに、テストはテストの順序とは無関係で、さらにidempotentとなっています。

tearDown()メソッドでsetUp()メソッドのデータベースを変更して、変更をロールバックするか、テスト用に適切な値を持つテストデータベースを設定するかを選択します。

多分私はここに何かを見逃しているかもしれませんが、通常はあなたはそれを望んではいけません。

+23

しかし、これは問題ではありません。 – Ralph

+7

@Ralphしかし、それはまだ正しい答えです。 –

+6

私はjunitテストをロールバックしないのは本当に良い理由があります。それで、 "正しい答え"はあなたがそれをしてはいけないということではありません。正しい答えは、どのように説明できる人かです。 – user829237

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は正解で正しい答えを提供するために+1ですが、私は他の答えを好む –

0

私はラルフの答えに同意するものとします。

伝播.REQUIRES_NEWは、新しいトランザクションを作成します。これは、テストが実行されているメインのトランザクションルートとはおそらく一致しません。

私の簡単な経験では、注釈@Transactionalが適切にこの1に(ラルフによって示されるように)特定の現在のロールバック句を委任、すべての単一のテストを実行すべきでトランザクションコンテキストを定義していきます。

ラルフの答えは有用であり、同時にSnicolasの答えはテストのコンテキストを管理する特定のケースに関係しています。 冪等位は、積分と自動テストの基本ですが、それらを実装する方法は異なるはずです。 質問は、どのような方法がありますか?そして、そのメソッドにはどのような振る舞いがありますか?

[...] 
    @Transactional 

    public class Test { 

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

    [...] 

だけ注釈ロールバックを追加し、falseにフラグを設定する簡単な質問コヒーレントな方法:)

6

です。公式ドキュメントから

@Test 
    @Rollback(false) 
1

:デフォルトでは

、テストトランザクションは自動的にテストの 完了した後にロールバックされます。しかし、トランザクションのコミットやロールバック 動作が@Commitがトランザクション試験方法 のトランザクションが後にコミットする必要があることを示し@Commitと@Rollback 注釈

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

経由宣言構成することができます試験方法は完了した。 @を@Rollback(false)に直接置き換えて使用すると、 はコードの意図を明示的に伝えることができます。

+0

私にとって非常に混乱していたのは、通常どおりどこでも例外が吹き飛ばされてもテストがコミットするということです。@Transactional on businessテストメソッドとは対照的にクラス)を使用して、txnロールバックをトリガーします。 –

+0

チェックされている例外のみ。チェックを外すとロールバックされます。 https://stackoverflow.com/questions/3701376/rollback-on-every-checked-exception-whenever-i-say-transactional – harryssuperman

関連する問題