私はビジネスサービスをテストするためにmockitoを使用していますが、モックしたいユーティリティを使用しています。異なる引数を持つユーティリティの各サービスメソッドには、少なくとも2〜3回の呼び出しがあります。
同じメソッドで異なる引数に対して複数のwhen(...).thenReturn(...)
を使用する推奨方法はありますか?
内部でany()
marcherも使用したいと思います。出来ますか?
更新:サンプルコード。
@Test
public void myTest() {
when(service.foo(any(), new ARequest(1, "A"))).thenReturn(new AResponse(1, "passed"));
when(service.foo(any(), new ARequest(2, "2A"))).thenReturn(new AResponse(2, "passed"));
when(service.foo(any(), new BRequest(1, "B"))).thenReturn(new BResponse(112, "passed"));
c.execute();
}
public class ClassUnderTest {
Service service = new Service();
public void execute() {
AResponse ar = (AResponse) service.foo("A1", new ARequest(1, "A"));
AResponse ar2 = (AResponse) service.foo("A2", new ARequest(2, "2A"));
BResponse br = (BResponse) service.foo("B1", new BRequest(1, "B"));
}
}
public class Service {
public Object foo(String firstArgument, Object obj) {
return null; //return something
}
}
1つの方法は、1つのthenReturn
呼び出しだけですべての期待される結果を提供するために、引数を制限しすぎないようにすることです。
たとえば、このメソッドをモックしたいとしましょう:
public String foo(String firstArgument, Object obj) {
return "Something";
}
次に、以下のように必要な数の結果を提供して、それをモックすることができます。
// Mock the call of foo of any String to provide 3 results
when(mock.foo(anyString(), anyObject())).thenReturn("val1", "val2", "val3");
パラメータを指定してfoo
を呼び出すと、それぞれ「val1
"、" val2
」、その後の呼び出しは「val3
"。
渡された値を気にするが、呼び出しシーケンスに依存したくない場合は、thenAnswer
を使用して、現在のように2番目の引数に一致するが、3つの異なるthenReturn
。
when(mock.foo(anyString(), anyObject())).thenAnswer(
invocation -> {
Object argument = invocation.getArguments()[1];
if (argument.equals(new ARequest(1, "A"))) {
return new AResponse(1, "passed");
} else if (argument.equals(new ARequest(2, "2A"))) {
return new AResponse(2, "passed");
} else if (argument.equals(new BRequest(1, "B"))) {
return new BResponse(112, "passed");
}
throw new InvalidUseOfMatchersException(
String.format("Argument %s does not match", argument)
);
}
);
適切な方法は、eq()
を使用して引数を一致させることですが、それを行いたくない場合は、複数の戻り値を記録できます。
when(someService.doSomething(any(SomeParam.class))).thenReturn(
firstReturnValue, secondReturnValue, thirdReturnValue
);
これで、最初の呼び出しはfirstValue
、2番目のsecondValue
、およびそれに続くすべてのthirdValue
を返します。
私は思う:「推奨」の方法はあなたのために働くものだろう。そして、それは最小限のコーディング努力でもたらされます。
テストを実行するために必要な仕様を提供する必要があります。それを回避する方法はありません。
使用する引数を本当に気にする場合は、それに応じて指定する必要があります。気にしない場合; any()
を使用します。