3

各テストケースの後にロールバックするようにSpring/JUnitを構成する方法を知っています。私が求めているのは、すべてのテストケースに対して1つのトランザクションを開始してロールバックする方法です。

@BeforeClassを使用して、いくつかのテストケース用にHSQLDBを準備しています。次に、@AfterClassのすべてのテストケースの終了後に変更をロールバックします。

このロールバックを実現するための最良の方法は何ですか?

これが私のコード例です:

@BeforeClass
public static void setupDB(){
ApplicationContext context = new ClassPathXmlApplicationContext(
        "classpath:/spring/applicationContext-services-test.xml");
//- get beans and insert some records to the DB
...
}

@AfterClass
public static void cleanUp(){
   ??? what should go here?
}

AfterClassでロールバックを行うための最良の方法に関するアイデアはありますか?

ありがとうございます..

4

4 に答える 4

5

各テストの後にロールバックして Spring を使用することが許容される場合は、私のプロジェクトからの次のスニペットが役立つ場合があります。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:/net/sukharevd/shopzilla/model/application-context-dao.xml" })
@TestExecutionListeners(DependencyInjectionTestExecutionListener.class)
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
@Transactional
public class HibernateCategoryDaoTest extends AbstractTransactionalJUnit4SpringContextTests {
于 2012-07-08T22:52:10.973 に答える
3

おそらく、クラスの後ではなく、各テストの後にロールバックを実行したいと思うでしょう。テストは毎回同じ順序で実行されるとは限らないため、異なる結果が得られる可能性があります。単体テストは分離する必要があります。

春のテストランナーを使用して、クラスに注釈を付け、トランザクションをロールバックできます

@RunWith(SpringJUnit4ClassRunner.class)
@TransactionConfiguration(defaultRollback=true)
public static class YourTestClass {

    @Test
    @Transactional
    public void aTest() {
        // do some db stuff that will get rolled back at the end of the test
    }

}

一般的には、単体テストで実際のデータベースにアクセスしないようにする必要があります。データベースにヒットするテストは、通常、統合レベルのテスト (または受け入れテストのようなさらに粗い粒度のテスト) です。DBUnit http://www.dbunit.org/フレームワークは、単体テスト用のデータベースをスタブ化するために使用されるため、実際のデータベースを使用する必要はありません。

于 2012-07-08T22:53:14.100 に答える
2

Spring/JUnit だけを使用して (DBUnit を使用せずに)、この問題を解決することができました。つまり、解決策はtransactionManager.getTransaction(def).setRollbackOnly();@BeforeClass を呼び出すことでした。

最初に、私が何をしようとしているのかを説明しましょう。私の主な動機は、この流れに関するものでした。

1. トランザクションを開始します
。 2. ロード テスト データを挿入します
。 3. 同じテスト データに対して複数のテスト ケースを実行します
。 4. テスト データをロールバックします。

@BeforeClass で負荷テスト データを作成しているので、@AfterClass でロールバックしようとしていました。@BeforeClass でのみトランザクションをロールバックするように指示できるので、これは不要のようです。

だからここに私がそれをした方法があります:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:/spring/applicationContext-services-test.xml")
@TestExecutionListeners(inheritListeners = false, listeners = { SpecialDependencyInjectionTestExcecutionListener.class })
@TransactionConfiguration(defaultRollback = true)
@Transactional
public class loadTest {
...
private static HibernateTransactionManager transactionManager;
...

@BeforeClass
public static void setupDB() {
  //- set the transaction to rollback only. We have to get a new transaction for that.
  DefaultTransactionDefinition def = new DefaultTransactionDefinition();
  def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
  transactionManager.getTransaction(def).setRollbackOnly();
  ...
  //- start loading the data using the injected services.
  ...
}

これは、クラスの最後にロールバックするのに役立ちました。

PS Theは、 @BeforeClass を呼び出す前に application.context を強制的にロードするために beforeTestClass をオーバーライドするために使用しSpecialDependencyInjectionTestExcecutionListenerた拡張機能です。DependencyInjectionTestExecutionListenerDmitriy は、私が心に抱えていた別の問題を解決するためのヒントであったこのリスナーを強調しました。

ハイライトと提案を手伝ってくれたすべての人に感謝し、まとめてこの解決策に導きました.

ダフィール

于 2012-07-09T23:12:53.490 に答える
0

Spring を使用していなかったとしましょう。(Springを使用しているため、ここでの他の回答の方が優れています。)次に、3つの選択肢があります。

  1. dbunitを使用して、データのロード/クリーンアップを処理します。(サイトは現在ダウンしていますが、Google で検索すると、いくつかのチュートリアルが表示されます。)
  2. 手動更新の手動削除を作成する
  3. セットアップの最初のステップとして、データベースにロールバック ポイントを作成します。Oracleでこれを行う方法は次のとおりです。
于 2012-07-09T03:14:28.927 に答える