Spy를 이용하면 실제 객체에 대한 검증 및 테스트를 할 수 있게 된다.
즉, mocking하지 않은 object에 대해서도 spy를 해주면 assertEquals나 verify를 할 수 있다.
예제를 통해 확인해보자.
public class SpyTest {
@Test
public void spyTest() {
List<String> list = spy(new ArrayList<>());
list.add("crocus");
assertEquals("crocus", list.get(0));
verify(list, times(1)).add(any());
}
}
우선 실제 객체인 list가 존재하고 있고, 이 객체는 mock되지 않았기 때문에 어떠한 방법으로도 verify나 assert를 할 수 없다.
하지만 위와 같이 spy()로 실제 객체를 감싸주면 해당 list를 spy하기 시작하고 list.add("crocus");를 하여도 해당 객체의 진행 과정들을 테스트 할 수 있게 된다.
추가적으로 spy를 하고 있기 때문에 모킹까지 가능해진다.
spy를 통해 mocking을 할수 없는 코드
public class SpyTest {
@Test
public void spyTest() {
List<String> list = spy(new ArrayList<>());
when(list.get(0)).thenReturn("world");
assertEquals("world", list.get(0));
}
}
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.rangeCheck(ArrayList.java:657)
at java.util.ArrayList.get(ArrayList.java:433)
at com.demo.testing.mockito.case1.SpyTest.spyTest(SpyTest.java:21)
...
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
spy를 통해 mocking을 할수 있는 코드
public class SpyTest {
@Test
public void spyTest() {
List<String> list = spy(new ArrayList<>());
doReturn("world").when(list).get(0);
assertEquals("world", list.get(0));
}
}
when thenReturn절을 사용하여 spy를 모킹하고자 하면 위와 같이 에러를 나타내게 된다.
when(list.get(0))는 list.get을 호출하는 순간 스터빙되어 에러가 나지만
when(list).get(0)는 list에 대한 모킹이 이뤄지고 난 후 get(0)가 스터빙되기에 괜찮기 때문이다.
따라서 spy를 모킹할 때는 doReturn 방식을 쓰는것을 권장한다.
doReturn() is similar to stubbing a method and returns the expected value.
But this is used only when when(mock).thenReturn(return) cannot be used.
when-thenReturn is more readable than doReturn(), also doReturn() is not type safe.
thenReturn checks method return types and raises compilation error if an unsafe type is passed.
'Applied > Unit Test' 카테고리의 다른 글
Custom Matcher 구현하여 테스트에서 사용하기 (0) | 2021.03.05 |
---|---|
블랙박스 테스트, 화이트박스 테스트 개념 (0) | 2020.04.27 |
[JUnit] Test Rule 개념 및 코드 (0) | 2020.04.25 |
[Robolectric] robolectric shadow bitmap 관련 참고 코드 (0) | 2020.04.21 |
[Robolectric] Robolectric을 이용한 Parameterized testing (0) | 2020.04.17 |