반응형

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.

 

www.oreilly.com/library/view/test-driven-development-with/9781783283293/ch06s10.html#:~:text=doReturn()%20is%20similar%20to,()%20is%20not%20type%20safe.

반응형