読者です 読者をやめる 読者になる 読者になる

mike-neckのブログ

JavaかJavaFXかJavaEE(なんかJava8が多め)

JUnit4.12時代のParameterized Test

JUnitに追いつこう(2周回遅れ、男子一万メートルだと2分近くの差、箱根駅伝なら4分40秒の差)という趣旨のエントリーです。

要約はこっちを見るほうが早かった

kyon-mm.hatenablog.com

irof.hateblo.jp

Parameterized Test

Parameterized TestがこれまではIterable<Object[]>だったのが、Iterable<Object>になったらしい。で、これに合わせるかのようにIntelliJ IDEAもParameterized Testでテストデータごとに結果を表示・再実行できるようになってた。で僕は、これまでパラメタライズドテストする場合は、Iterable<Object[]>を嫌って@RunWith(Theories.class)でテストしてたわけで、IntelliJ IDEAがParameterized Testに対応したのが何が嬉しいのかわかってなかったのです。

ものは試しなので、早速Parameterized Testを書いてみます。

@RunWith(Parameterized.class)
public class StringLengthTest {

    private final TestParameter<String, Integer> param;

    public StringLengthTest(TestParameter<String, Integer> param) {
        this.param = param;
    }

    @Test
    public void testing() {
        param.stretchAndAssert(String::length);
    }

    @Parameters
    public static List<TestParameter<String, Integer>> data() {
        return Arrays.asList(
                new TestParameter<>("foo", 3),
                new TestParameter<>("bar", 3),
                new TestParameter<>("holiday", 6), // わざと間違えてる
                new TestParameter<>("monday", 6));
    }

    private static class TestParameter<I, E> {
        private final I in;
        private final E ex;

        private TestParameter(I in, E ex) {
            this.in = in;
            this.ex = ex;
        }

        I getInput() {
            return in;
        }
        E getExpected() {
            return ex;
        }

        void stretchAndAssert(Function<? super I, ? extends E> fun) {
            assertThat(fun.apply(in), is(ex));
        }
    }
}

で、こちらが実行結果

f:id:mike_neck:20150506080832p:plain

お、優秀優秀。しかも、パラメーターごとにテストの再実行ができるようになっていますね。

f:id:mike_neck:20150506081841p:plain

まあ、上のような単純な用途に関しては、@RunWith(Parameterized.class)でやって、組み合わせが多彩になる場合は@RunWith(Theories.class)でやるという住み分けもできそうです。

あと、Iterable<Object>になったことで、

mike-neck.hatenadiary.com

でやってた、サブクラスを作るのもやらなくてよくなったのが割りと地味に嬉しいですね。


結論

  • @RunWith(Theories.class)Iterable<T>でよくなってた。

おわり