私はMockitoをサービス後の単体テストに使用しています。 doAnswer
とthenReturn
をいつ使用するか混乱します。
誰かが私を詳しく助けてくれる?これまでのところ、私はthenReturn
でそれを試しました。
メソッド呼び出しをモックするときの戻り値がわかっているときは、thenReturn
またはdoReturn
を使用してください。この定義された値は、モックメソッドを呼び出すと返されます。
thenReturn(T value)
メソッドが呼び出されたときに返される戻り値を設定します。
@Test
public void test_return() throws Exception {
Dummy dummy = mock(Dummy.class);
int returnValue = 5;
// choose your preferred way
when(dummy.stringLength("dummy")).thenReturn(returnValue);
doReturn(returnValue).when(dummy).stringLength("dummy");
}
Answer
は、モックメソッドが呼び出されたときに追加のアクションを実行する必要がある場合に使用されます。このメソッド呼び出しのパラメータに基づいて戻り値を計算する必要があるとき。
Voidメソッドを汎用の
Answer
でスタブする場合はdoAnswer()
を使用してください。Answerは、実行されたアクションと、モックを操作したときに返される戻り値を指定します。
@Test
public void test_answer() throws Exception {
Dummy dummy = mock(Dummy.class);
Answer<Integer> answer = new Answer<Integer>() {
public Integer answer(InvocationOnMock invocation) throws Throwable {
String string = invocation.getArgumentAt(0, String.class);
return string.length() * 2;
}
};
// choose your preferred way
when(dummy.stringLength("dummy")).thenAnswer(answer);
doAnswer(answer).when(dummy).stringLength("dummy");
}
以下の場合、doAnswer
とthenReturn
は同じことを行います。
このBookServiceをモックしましょう
public interface BookService {
String getAuthor();
void queryBookTitle(BookServiceCallback callback);
}
doAnswer
およびthenReturn
を使用してgetAuthor()をスタブすることができます。
BookService service = mock(BookService.class);
when(service.getAuthor()).thenReturn("Joshua");
// or..
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
return "Joshua";
}
}).when(service).getAuthor();
doAnswer
を使用するときは、when
にメソッドを渡すことはできません。
// Will throw UnfinishedStubbingException
doAnswer(invocation -> "Joshua").when(service.getAuthor());
それで、いつdoAnswer
の代わりにthenReturn
を使うのでしょうか。私は2つのユースケースを考えることができます:
DoAnswerを使用すると、メソッド呼び出し時にいくつかの追加アクションを実行できます。たとえば、queryBookTitleでコールバックをトリガーします。
BookServiceCallback callback = new BookServiceCallback() {
@Override
public void onSuccess(String bookTitle) {
assertEquals("Effective Java", bookTitle);
}
};
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
BookServiceCallback callback = (BookServiceCallback) invocation.getArguments()[0];
callback.onSuccess("Effective Java");
// return null because queryBookTitle is void
return null;
}
}).when(service).queryBookTitle(callback);
service.queryBookTitle(callback);
Spy Mockitoでwhen-thenReturnを使用すると、実際のメソッドが呼び出されてから回答がスタブされます。このサンプルのように、実際のメソッドを呼び出したくない場合は、これが問題を引き起こす可能性があります。
List list = new LinkedList();
List spy = spy(list);
// Will throw Java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
when(spy.get(0)).thenReturn("Java");
assertEquals("Java", spy.get(0));
DoAnswerを使って安全にスタブすることができます。
List list = new LinkedList();
List spy = spy(list);
doAnswer(invocation -> "Java").when(spy).get(0);
assertEquals("Java", spy.get(0));
実際には、メソッドの呼び出し時に追加のアクションを実行したくない場合は、単にdoReturn
を使用できます。
List list = new LinkedList();
List spy = spy(list);
doReturn("Java").when(spy).get(0);
assertEquals("Java", spy.get(0));