공통점
- 테스트 대상 기능 중 일부 기능이 준비가 되지 않았을때 / 다른 시스템과 통신등이 필요한 경우 미리 리턴 값을 선언하여 테스트 할수 있다. / Stub
when(spyWhenService.callServerAPI("1")).thenReturn(true);
when(spyWhenService.callServerAPI("2")).thenReturn(false);
doReturn(true).when(spyWhenService).callServerAPI("1");
doReturn(false).when(spyWhenService).callServerAPI("2");
차이점
thenReturn
- 메소드를 실제 호출하지만 리턴 값은 임의로 정의 할 수 있다.
- 메소드 작업이 오래 걸릴 경우 끝날때까지 기다려야함
- 실제 메소드를 호출하기 때문에 대상 메소드에 문제점이 있을 경우 발견 할 수 있다.
doReturn
- 메소드를 실제 호출하지 않으면서 리턴 값을 임의로 정의 할 수 있다.
- 실제 메소드를 호출하지 않기 때문에 대상 메소드에 문제점이 있어도 알수가 없다.
public class WhenService {
public String getSystemInfo(String url) throws Exception {
boolean isOk = callServerAPI(url);
return isOk? "system123" : "none";
}
public boolean callServerAPI(String url) throws Exception {
System.out.println("좀 오래 걸리는 작업입니다.");
return true;
}
}
// given
WhenService realWhenService = new WhenService();
WhenService spyWhenService = spy(realWhenService);
// console에 좀 오래 걸리는 작업입니다 라는 메세지가 출력된다.
when(spyWhenService.callServerAPI("2")).thenReturn(false);
// console에 좀 오래 걸리는 작업입니다 라는 메세지가 출력되지 않는다.
doReturn(true).when(spyWhenService).callServerAPI("1");
// when
String result1 = spyWhenService.getSystemInfo("1");
// then
assertEquals("system123", result1);
// 아래와 같이 문제 점이 있는 메소드의 경우 thenReturn은 실제 메소드를 호출하기 때문에 테스트 도중 문제점을 발견 할 수 있다.
public boolean callServerAPI(String url) throws Exception {
System.out.println("좀 오래 걸리는 작업입니다.");
List list = null;
list.get(0);
return true;
}
기타
- 작업이 오래 걸리는 경우 또는 다른 시스템과 연동을 해야할 경우 doReturn이 좋겠지만 실제 메소드를 호출하지 않기 때문에 되도록이면 thenReturn을 사용
// mock을 사용할 경우 CALLS_REAL_METHODS 함께 사용
WhenService spyWhenService = mock(WhenService.class, CALLS_REAL_METHODS);
when(spyWhenService.callServerAPI("1")).thenReturn(true);
when(spyWhenService.callServerAPI("2")).thenReturn(false);