16

jUnit を使用して、データベースにアクセスするアプリケーションの統合テストを管理しています。テスト データの設定は時間のかかる操作であるため、@BeforeClassテスト クラスごとに 1 回だけ実行されるメソッドでそれを行ってきました (テスト メソッドごとに 1 回実行されるメソッドとは対照的@Beforeです)。

ここで、データ層の構成についていくつかの異なる順列を試して、それぞれの構成ですべてのテストを実行したいと思います。Parameterizedこれは、テスト ランナーの自然な使い方のようです。問題は、Parameterizedクラスコンストラクターにパラメーターを提供し、@BeforeClassメソッドが抽象的であり、クラスコンストラクターの前に呼び出されることです。

いくつかの質問、

パラメータの順列ごとParameterizedにメソッドを呼び出しますか、それとも 1 回だけ呼び出しますか?@BeforeClass

メソッドが繰り返し呼び出される場合、@BeforeClassメソッド内からパラメーター値にアクセスする方法はありますか?

これらのいずれでもない場合、この問題に対する最良の代替アプローチとして人々は何を提案しますか?

4

5 に答える 5

3

カスタムテストランナーが必要になると思います。私はあなたが抱えているのと同じ問題を抱えています (複数の高価な構成を使用して同じテストを実行する必要があります)。セットアップをパラメーター化する方法が必要です。おそらく、パラメーター化されたランナーで使用されるものと同様の @Parameter 注釈を使用しますが、インスタンス フィールドの代わりに静的メンバー フィールドを使用します。カスタム ランナーは、@Parameter アノテーションを持つすべての静的メンバー フィールドを見つけてから、静的 @Parameter フィールドごとに 1 回 (おそらく基本的な BlockJunit4ClassRunner を使用して) テスト クラスを実行する必要があります。@Parameter フィールドは、おそらく @ClassRule である必要があります。

Andy on Software は、カスタム テスト ランナーの開発に優れた仕事をしており、これらのブログ投稿で非常に明確に説明してます

于 2013-11-25T21:15:27.437 に答える
1

@BeforeClass は、あなたの例では一度だけ呼び出されます。名前を考えると、これは理にかなっています-クラスの前に!

テストで別のデータが必要な場合は、次の 2 つの選択肢が考えられます。

  1. @Before でそのデータを設定して、テスト固有にする
  2. 同じデータで実行するテストを個別のテスト クラスにグループ化し、それぞれに @BeforeClass を使用します。
于 2012-06-27T02:32:07.473 に答える
0

この初期化ロジックは、テストクラスのコンストラクターで呼び出すことができます。静的変数で使用される最後のパラメーターを追跡します。変更されたら、新しいパラメータのクラスを設定します。

AfterClassに相当するものは考えられません。

于 2013-02-12T22:42:16.453 に答える
0

これは古い質問ですが、おそらく同様の問題を解決する必要がありました。今のところ、以下のソリューションを使用しました。これは、基本的に、このメカニズムが必要なときに重複を避けるために、汎用抽象基本クラスを使用した TREE の (更新された) 回答の実装です。

具体的なテストは、それぞれ Supplier< T > を含む単一要素配列の iterable を返す @Parameters メソッドを提供します。これらのサプライヤは、具体的なテスト メソッドで必要な実際の入力ごとに 1 回だけ実行されます。

@RunWith(Parameterized.class)
public class AbstractBufferedInputTest<T> {

private static Object INPUT_BUFFER;

private static Object PROVIDER_OF_BUFFERED_INPUT;

private T currentInput;

@SuppressWarnings("unchecked")
public AbstractBufferedInputTest(Supplier<T> inputSuppler) {
    if (PROVIDER_OF_BUFFERED_INPUT != inputSuppler) {
        INPUT_BUFFER = inputSuppler.get();
        PROVIDER_OF_BUFFERED_INPUT = inputSuppler;
    }
    currentInput = (T) INPUT_BUFFER;
}

/**
 * 
 * @return the input to be used by test methods
 */
public T getCurrentInput() {
    return currentInput;
}

}
于 2015-09-23T07:31:08.613 に答える
-1

@Before メソッドで初期化を行い、インスタンス変数に書き込みますが、null をテストすることができます。

@RunWith(value = Parameterized.class)
public class BigThingTests {
  private BigThing bigThing;

  @Before
  public void createBitThing() {
    if (bigThing == null) {
      bigThing = new BigThing();
    }
  }

...
}

BigThingTestsパラメータのセットごとに の新しいインスタンスが作成され、bigThing新しいインスタンスごとに null に設定されます。ランナーはシングルスレッドであるため、Parameterized複数の初期化について心配する必要はありません。

于 2013-02-01T16:50:25.310 に答える