Mockito——我知道间谍在对象上调用实际方法,而模拟在双对象上调用方法。此外,除非有代码气味,否则要避免间谍。然而,间谍是如何工作的?我应该在什么时候使用他们?它们与模拟有什么不同?
TL;博士版本,
通过mock,它为您创建了一个简单的shell实例。
List<String> mockList = Mockito.mock(ArrayList.class);
使用间谍,您可以部分嘲笑现有实例
List<String> spyList = Mockito.spy(new ArrayList<String>());
Spy的典型用例:类有一个参数化的构造函数,您希望首先创建对象。
两者都可以用于模拟方法或字段。不同之处在于,在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的区别。
从技术上讲,“模拟人”和“间谍”都是一种特殊的“测试替身”。
不幸的是,莫基托把这种区分搞得很奇怪。
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