답변:
메서드 호출을 모의 할 때 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()
generic으로 void 메서드를 스텁하려는 경우 사용 합니다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
단지와 함께 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
합니까? 두 가지 사용 사례를 생각할 수 있습니다.
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);
when-thenReturn on Spy Mockito를 사용하면 실제 메서드를 호출 한 다음 답변을 스텁합니다. 이 샘플과 같이 실제 메서드를 호출하지 않으려면 문제가 발생할 수 있습니다.
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;}
eclipse에서 "Answer는 원시 유형입니다. 제네릭 유형 Answer <T>에 대한 참조는 매개 변수화되어야합니다"에 대한 경고가 표시됩니다. 이 문제를 해결할 수있는 방법이 있습니까 (경고 ofc 무시 제외)?
code = UUID.randomUUID()
, 나는 이것을 구현하는 것은 불가능 발견mockito
.