Mockito - @Spy vs @Mock

后端 未结 7 1004
南旧
南旧 2020-11-29 17:33

Mockito - I understand a spy calls the real methods on an object, while a mock calls methods on the double object. Also spies are to be avoided unless there is a code smell.

7条回答
  •  被撕碎了的回忆
    2020-11-29 18:27

    Both can be used to mock methods or fields. The difference is that in mock, you are creating a complete mock or fake object while in spy, there is the real object and you just spying or stubbing specific methods of it.

    While in spy objects, of course, since it is a real method, when you are not stubbing the method, then it will call the real method behavior. If you want to change and mock the method, then you need to stub it.

    Consider the example below as a comparison.

    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.mockito.Mock;
    import org.mockito.Spy;
    import org.mockito.runners.MockitoJUnitRunner;
     
    import java.util.ArrayList;
    import java.util.List;
     
    import static org.junit.Assert.assertEquals;
    import static org.junit.Assert.assertNull;
    import static org.mockito.Mockito.doReturn;
    import static org.mockito.Mockito.when;
     
    @RunWith(MockitoJUnitRunner.class)
    public class MockSpy {
     
        @Mock
        private List mockList;
     
        @Spy
        private List spyList = new ArrayList();
     
        @Test
        public void testMockList() {
            //by default, calling the methods of mock object will do nothing
            mockList.add("test");
    
            Mockito.verify(mockList).add("test");
            assertEquals(0, mockList.size());
            assertNull(mockList.get(0));
        }
     
        @Test
        public void testSpyList() {
            //spy object will call the real method when not stub
            spyList.add("test");
    
            Mockito.verify(spyList).add("test");
            assertEquals(1, spyList.size());
            assertEquals("test", spyList.get(0));
        }
     
        @Test
        public void testMockWithStub() {
            //try stubbing a method
            String expected = "Mock 100";
            when(mockList.get(100)).thenReturn(expected);
     
            assertEquals(expected, mockList.get(100));
        }
     
        @Test
        public void testSpyWithStub() {
            //stubbing a spy method will result the same as the mock object
            String expected = "Spy 100";
            //take note of using doReturn instead of when
            doReturn(expected).when(spyList).get(100);
     
            assertEquals(expected, spyList.get(100));
        }
    }
    

    When shoud you use mock or spy? If you want to be safe and avoid calling external services and just want to test the logic inside of the unit, then use mock. If you want to call external service and perform calling of real dependency, or simply say, you want to run the program as it is and just stub specific methods, then use spy. So that’s the difference between spy and mock in mockito.

提交回复
热议问题