当前位置: 首页 > 知识库问答 >
问题:

莫基托-@间谍vs@Mock

陶星波
2023-03-14

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

共有3个答案

傅浩漫
2023-03-14

TL;博士版本,

通过mock,它为您创建了一个简单的shell实例。

List<String> mockList = Mockito.mock(ArrayList.class);

使用间谍,您可以部分嘲笑现有实例

List<String> spyList = Mockito.spy(new ArrayList<String>());

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

朱承载
2023-03-14

两者都可以用于模拟方法或字段。不同之处在于,在mock中,您创建的是一个完整的mock或伪对象,而在spy中,存在真实的对象,您只需对其特定方法进行监视或存根。

而在窥探对象的时候,当然,既然是真实的方法,那么当你不固执的时候,就会调用真实的方法行为。如果你想改变和模拟方法,那么你需要存根它。

考虑下面的例子作为比较。

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的区别。

梁昊天
2023-03-14

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

不幸的是,莫基托把这种区分搞得很奇怪。

mockito中的mock是其他mocking框架中的正常mock(允许存根调用;也就是说,从方法调用中返回特定的值)。

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

 类似资料:
  • 我对Mockito和带有“间谍”注释的字段有点混乱。 我想测试这个类: 因此,我创建了一个测试类,如下所示: 当Mockito实例categoryServiceImpl将categoryRepository作为模拟类注入时,但它不知道如何创建boundMapper。这个类依赖于mapper,所以我重写了代码: 但是现在的问题是在Mockito注入映射器之前执行了边界映射器的创建,所以我得到了一个N

  • 我对莫基托有疑问。我想测试这个简单的类: 我写了这个简单的测试: 此测试运行时没有错误。我等待它没有编译,因为没有任何对userService方法的调用…

  • Mockito似乎是一个非常好的Java存根/模拟框架。唯一的问题是我找不到任何关于使用API的最佳方法的具体文档。测试中使用的常用方法包括: 当您在实践中看到Mockito的示例时,您会看到如下代码: 从我读过的所有文档中,我已经识别了几个Mockito“语法”的“模式”,这些“语法”是通过将这些方法调用像上面的示例一样链接在一起而获得的。我发现的一些常见模式有: 当/然后:当(你的方法())。

  • 为什么Mockito会吞噬堆栈痕迹?例如,如果我有一个 和一个测试,例如 抛出的异常看起来总是 (这里提供的示例只是一个简化--我要处理更多的间接、类等等。我不能让Mockito吞噬部分模拟堆栈跟踪的关键部分……)

  • 试图将我的项目从Java 11更新到Java 17,在一个特定测试中,Mockito出现了一个意外错误。 投掷 不知道为什么Mockito这次考试不及格。

  • 测试类别 测试类别 详图搁置器 当我尝试模拟方法HistoryFromStrgyTable()的数据时,它实际上是在调用HistoryFromStrgyTable(),而不是从mockHistoryFromStrgyTable()获取数据。 我的测试用例在这一行失败了 谁能帮我一下吗。我不明白怎么了。我还将方法mockHistoryFromStrgyTable()从private更改为public