2

現在、私は JUnit 4 を使用しており@BeforeClass、ユーザー スキーマのリセットやサンプル データの準備に必要なすべてをメソッドでセットアップしています。このアプローチが気に入らないわけではありませんが、次の理由で非常にイライラすることがわかりました。

  • Parameterizedアノテーションを使用して、まったく同じテストを異なる入力データで実行しています。静的メソッドで動作する@BeforeClassため、パラメーター化は機能しません。@BeforeClass

@BeforeClassつまり、ロジックを保持したい場合は、テストを複製する必要があります。@After は使用できません@Before。これらはすべてのテストの後に発生し、オーバーヘッドになるためです。

テストを処理する抽象クラスと、試したいすべてのグループ パラメータのサブクラスを記述して、テスト コードを 1 回だけ記述できるようにするという意味で、この単体テストをリファクタリングできると考えていました。

次の出発点でよりクリーンなオプションを提案できることを願っています: を使用し@Parameterized、「データベース」メソッドをパラメーター グループごとに 1 回だけ実行する必要があります。

編集:

これは、BeforeClass を使用しない私のクラスの例です

RunWith(LabelledParameterized.class)
public class TestCreateCampaign extends AbstractTestSubscriberCampaign {

    public TestCreateCampaign(String label, String apiKey, String userKey,
            int customerId) {
        super(label, apiKey, userKey, customerId);
    }

    @Before
    public void setUp() throws Exception {
        super.setUp();
    }

    @After
    public void tearDown() throws Exception {
        super.tearDown();
    }

    @Parameters
    public static Collection<Object[]> generatedData() {
        return DataProvider.generatedCorrectSubscriberData();
    }

    @Test
    public void testCreateEmailCampaignBothTriggered() {

        // TEST

    }

    @Test
    public void testCreateTextCampaignTriggered() {

        // TEST

    }

    @Test
    public void testCreateTextCampaignTest() {

        // TEST

    }

    // Other Tests

}
4

3 に答える 3

0

パラメータ化されたテストクラスのコンストラクタからセットアップメソッドを呼び出すのはどうですか?

編集:

OK、これを自動的に行うものは何も知りませんが、コードを記述してRuleそれを行うことができると思います。Ruleゼロからextendを実装することもできますExternalResource。これが私が思うことです。

  1. コンストラクターは、テストクラスのインスタンスとインスタンスを取得しExternalResourceます。
  2. コンストラクターでは、アノテーションを含むメソッドのリストを検索し@Test、カウントを取得します。反復回数を0に設定します。
  3. beforeメソッドでは、反復回数をインクリメントし、インクリメント後1(または前0)の場合は、before渡されたでメソッドを呼び出しExternalResourceます。
  4. このafterメソッドでは、反復回数がテストの数と等しいかどうかを確認し、等しい場合はafter、合格したメソッドを呼び出しますExternalResource

およびメソッドはでExternalResourceあるため、別のコールバッククラス/インターフェイスを使用する必要がある場合があります。本当にクールになりたい場合は、ルールで独自のアノテーションとアノテーションを定義し、渡されたインスタンスでそれらのメソッドを検索します。beforeafterprotectedBeforeParametersAfterParameter

これを開発する場合は、投稿するか、JUnitに送信して含めてください。

これが私が思いついたものですが、私が望むほど良くはありません:

@RunWith(Parameterized.class)
public class TestExample {

private interface BeforeAfter {
    void before();

    void after();
}

public static class Resource extends ExternalResource {

    private final int count;
    private final BeforeAfter ba;
    private int iteration = 0;

    Resource(Object instance, BeforeAfter ba) {
        int localCount = 0;
        for (Method method : instance.getClass().getMethods()) {
            if (method.getAnnotation(Test.class) != null) {
                localCount++;
            }
        }
        this.count = localCount;
        this.ba = ba;
    }

    @Override
    protected void before() throws Throwable {
        if (iteration == 0) {
            ba.before();
        }

        iteration++;
    }

    @Override
    protected void after() {
        if (iteration == count) {
            ba.after();

            iteration = 0;
        }
    }
}

@Parameters
public static Iterable<Object[]> data() {
    return Arrays.asList(new Object[][] { { 3, 0 }, { 4, 1 } });
}

@Rule
public static Resource resource = new Resource(new TestExample(0, 0), new BeforeAfter() {

    @Override
    public void before() {
        System.out.println("setup");
    }

    @Override
    public void after() {
        System.out.println("cleanup");

    }
});

private int fInput;
private int fExpected;

public TestExample(int input, int expected) {

    // System.out.println("Constructor invoked" + fInput);
    fInput = input;
    fExpected = expected;
}

@Test
public void test1() {
    System.out.println("test1 fInput=" + fInput);
}

@Test
public void test2() {
    System.out.println("test2 fInput=" + fInput);
}
}

をもたらしました:

setup
test1 fInput=3
test2 fInput=3
cleanup
setup
test1 fInput=4
test2 fInput=4
cleanup
于 2012-10-19T12:41:20.943 に答える