首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Mockito - @Spy vs @Mock

Mockito - @Spy vs @Mock
EN

Stack Overflow用户
提问于 2015-02-03 17:38:15
回答 8查看 118.3K关注 0票数 131

Mockito -我知道间谍调用对象上的真正方法,而模拟调用double对象上的方法。此外,除非有代码气味,否则要避免间谍活动。然而,间谍是如何工作的,我应该在什么时候实际使用它们?它们和mock有什么不同?

EN

回答 8

Stack Overflow用户

发布于 2015-02-04 00:20:22

从技术上讲,“模拟”和“间谍”都是一种特殊的“替身测试”。

不幸的是,Mockito把这种区别搞得很奇怪。

中的模拟是其他模拟框架中的普通模拟(允许您对调用进行存根;即从方法调用中返回特定值)。

中的间谍是其他模拟框架中的部分模拟(部分对象将被模拟,部分将使用真实的方法调用)。

票数 117
EN

Stack Overflow用户

发布于 2017-12-19 23:22:52

两者都可以用来模拟方法或字段。不同之处在于,在mock中,您创建了一个完整的mock或伪对象,而在spy中,存在真实的对象,您只需刺探或截取它的特定方法。

当然,在spy对象中,因为它是一个真实的方法,所以当你没有截断该方法时,它将调用真实的方法行为。如果您想要更改和模拟该方法,则需要将其存根。

请考虑下面的示例作为比较。

代码语言:javascript
复制
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<String> mockList;
 
    @Spy
    private List<String> 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));
    }
}

什么时候你应该使用mock或spy?如果您想要安全,避免调用外部服务,并且只想测试单元内部的逻辑,那么可以使用mock。如果您想调用外部服务并执行实际依赖项的调用,或者只是简单地说,您想按原样运行程序并仅存根特定的方法,则使用spy。这就是mockito中spy和mock的区别。

票数 78
EN

Stack Overflow用户

发布于 2017-08-29 03:41:55

TL;DR版本,

使用模拟,它可以为您创建一个基本的shell实例。

代码语言:javascript
复制
List<String> mockList = Mockito.mock(ArrayList.class);

使用spy,您可以在现有的实例上部分模拟

代码语言:javascript
复制
List<String> spyList = Mockito.spy(new ArrayList<String>());

Spy的典型用例:该类有一个参数化的构造函数,您希望首先创建对象。

票数 20
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28295625

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档