web-dev-qa-db-ja.com

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に設定しますか?

前もって感謝します、

25
Juan

期待どおりに動作するはずですが、テスト対象のクラス内で別のトランザクションを開いているか、他の機能/バグがどこかにある可能性があります。

ところで、この注釈は非常に優れているはずです。

@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トランザクション管理

50
Ralph

データベースを変更し、変更を保持するテストを望むのは奇妙です。テストは直交することになっています。テストは他に依存しません。さらに、テストはテストの順序とは独立しており、 idempotent であることも想定されています。

したがって、setUp()メソッドでデータベースを変更し、tearDown()メソッドで変更をロールバックするか、テスト用のいくつかの適切な値を使用してテストデータベースをセットアップします。 。

たぶん私はここで何かを見逃していますが、通常あなたはそれを望まないはずです。

11
Snicolas

Rollbackアノテーションを追加し、フラグをfalseに設定するだけです。

   @Test
   @Rollback(false)
11
grep

公式ドキュメントから:

デフォルトでは、テストトランザクションはテストの完了後に自動的にロールバックされます。ただし、トランザクションのコミットおよびロールバックの動作は、@ Commitおよび@Rollbackアノテーションを使用して宣言的に構成できます。

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

@Commitは、テストメソッドの完了後にトランザクションテストメソッドのトランザクションをコミットする必要があることを示します。 @Commitは、コードの意図をより明確に伝えるために、@ Rollback(false)を直接置き換えるものとして使用できます。

3
harryssuperman
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...
      }
0
Vicky

ラルフの答えに同意します。

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

私の簡単な経験では、アノテーション@ Transactionalは、すべてのテストを実行するトランザクションコンテキストを適切に定義し、これに特定の現在のロールバックを委任します。句(Ralphが示すとおり)。

Ralphの答えは有用であり、同時にSnicolasの答えはテストのコンテキストを管理する特定のケースに関係しています。 idempotenceは、統合および自動テストの基本ですが、それらを実装するさまざまな方法である必要があります。問題は、どのような方法がありますか?そして、これらのメソッドにはどのような振る舞いがありますか?

   [...]
   @Transactional

   public class Test {

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

   [...]

シンプルで、質問に首尾一貫した方法です:)

0
AL3X