回答:
メソッド呼び出しをモックするときの戻り値がわかっている場合に使用する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
モックされたメソッドが呼び出されたときに追加のアクションを実行する必要がある場合、たとえば、このメソッド呼び出しのパラメーターに基づいて戻り値を計算する必要がある場合に使用されます。
doAnswer()
ジェネリックでvoidメソッドをスタブしたい場合に使用しますAnswer
。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");
}
Answer
just with を実装しreturn UUID.randomUUID();
ます。
Answer
は関数型インターフェースであるため、Java 8ではラムダ式に置き換えることができます。が十分にクリーンでない場合、他の通常の異常なリファクタリングが可能です。
doAnswer
次のthenReturn
場合も同じことを行います。
このBookServiceをモックしましょう
public interface BookService {
String getAuthor();
void queryBookTitle(BookServiceCallback callback);
}
doAnswer
およびを使用してgetAuthor()をスタブできthenReturn
ます。
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));
doAnswer(new Answer() { ... return null;}
、「答えは生の型です。総称型Answer <T>への参照はパラメーター化する必要があります」という警告がEclipseで表示されます。これを解決する方法はありますか(警告ofcを無視することを除く)?
code = UUID.randomUUID()
、これをで実装することは不可能mockito
です。