public interface B { void foo(int s); } public class A { final B b; public A(B b) { this.b = b; } public void callB(int s) { b.foo(s * 2); } }コードの通り、クラス A はクラス B への 依存を持ち、「 A は、callB() の引数を 2倍して、B の foo() を呼び出す」というコラボレーションの仕様がある。
この A の B とのコラボレーションを検証したいが、assertX メソッドだとややこしくなるので、普通はモッキングの手法を使うことになる。
@RunWith(JMock.class) public class ATest { Mockery context = new JUnit4Mockery(); @Test public void testCallB() { final B b = context.mock(B.class); context.checking(new Expectations(){{ oneOf(b).foo(2); }}); new A(b).callB(1); } }ここでテスト値が 1 だけなのは不十分なので、-1, 0, 2 での検証も追加したくなったとする。以下のように共通メソッドにくくり出して、呼び出しを並べても良いが・・・
@Test public void testCallB() { final B b = context.mock(B.class); assertCallB(b, -1, -2); assertCallB(b, 0, 0); assertCallB(b, 1, 2); assertCallB(b, 2, 4); } void assertCallB(final B b, int param, final int expected) { context.checking(new Expectations(){{ oneOf(b).foo(expected); }}); new A(b).callB(param); }・・・ JUnitでは Parameterized という Suit Runner 派生クラスによる、Parameterized Test が標準でサポートされていて、こっちも活用してみたい。
ところが、アノテーションの仕組み上 RunWith を二重に指定する事はできない(できたとしても Runner の振る舞いがどう合成されるかは自明ではないが)ので、困ったことになる。
@RunWith(Parameterized.class) @RunWith(JMock.class) // 認められない public class ATest { @Parameters public static Collection<Object[]> params() { return Arrays.asList(new Object[][]{{-1, -2}, {0, 0}, {1, 2}, {2, 4}}); } Mockery context = new JUnit4Mockery(); final int param; final int expected; public ATest(int param, int expected) { this.param = param; this.expected = expected; } @Test public void testCallB() { final B b = context.mock(B.class); context.checking(new Expectations(){{ oneOf(b).foo(expected); }}); new A(b).callB(param); } }これを後で考えてみる。(←考えた[12/30])
0 件のコメント:
コメントを投稿