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 件のコメント:
コメントを投稿