💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# Mockito 注解– `@Mock`,`@Spy`,`@Captor`,`@InjectMock` > 原文: [https://howtodoinjava.com/mockito/mockito-annotations/](https://howtodoinjava.com/mockito/mockito-annotations/) 在此 Mockito 教程中,了解 **Mockito 注解**,例如`@Mock`,`@Spy`,`@Captor`,`@InjectMock`。 学习使用模仿注解为行为测试编写单元测试。 ## 1\. Mockito 注解 #### 1.1 `@Mock` `@Mock`注解用于创建和注入模拟实例。 我们不创建真实的对象,而是要求模拟为类创建一个模拟。 `@Mock`注解是`Mockito.mock(classToMock)`的替代方法。 它们都达到相同的结果。 通常认为使用`@Mock`是“**清洁器**”,因为我们没有用看起来都一样的样板分配填充测试。 使用`@Mock`注解: * 允许快速创建测试所需的对象。 * 最小化重复的模拟创建代码。 * 使测试类更具可读性。 * 由于使用字段名称来识别模拟,因此使验证错误更易于阅读。 在给定的示例中,我们模拟了`HashMap`类。 在实际测试中,我们将模拟实际的应用类。 我们在映射中放置了一个键值对,然后验证了对模拟映射实例执行了方法调用。 ```java @Mock HashMap<String, Integer> mockHashMap; @Test public void saveTest() { mockHashMap.put("A", 1); Mockito.verify(mockHashMap, times(1)).put("A", 1); Mockito.verify(mockHashMap, times(0)).get("A"); assertEquals(0, mockHashMap.size()); } ``` #### 1.2 `@Spy` `@Spy`注解用于**创建真实对象并监视该真实对象**。 间谍程序可以帮助调用对象的所有常规方法,同时仍可以跟踪每次交互,就像使用模拟一样。 请注意,在给定的示例中,由于我们向其中添加了一个键值对,因此映射的大小如何保持为 1。 我们还可以使用它的键取回添加到映射的值。 在模拟实例中是不可能的。 ```java @Spy HashMap<String, Integer> hashMap; @Test public void saveTest() { hashMap.put("A", 10); Mockito.verify(hashMap, times(1)).put("A", 10); Mockito.verify(hashMap, times(0)).get("A"); assertEquals(1, hashMap.size()); assertEquals(new Integer(10), (Integer) hashMap.get("A")); } ``` ###### `@Mock`和`@Spy`之间的区别 使用`@Mock`时,mockito 将创建类的准系统的 shell 实例,完全可以跟踪与之的交互。 这不是真实的对象,也不维护其状态更改。 使用`@Spy`时,mockito 创建类的真实实例并跟踪与之的每次交互。 它保持状态更改。 #### 1.3 `@Captor` `@Captor`注解用于创建`ArgumentCaptor`实例,该实例用于**捕获方法参数值**进行进一步的声明。 请注意,mockito 使用参数类的`equals()`方法验证参数值。 ```java @Mock HashMap<String, Integer> hashMap; @Captor ArgumentCaptor<String> keyCaptor; @Captor ArgumentCaptor<Integer> valueCaptor; @Test public void saveTest() { hashMap.put("A", 10); Mockito.verify(hashMap).put(keyCaptor.capture(), valueCaptor.capture()); assertEquals("A", keyCaptor.getValue()); assertEquals(new Integer(10), valueCaptor.getValue()); } ``` #### 1.4 `@InjectMock` 在模拟中,我们需要创建要测试的类的对象,然后插入其依赖项(*模拟*)以完全测试行为。 为此,我们使用`@InjectMock`注解。 `@InjectMock`标记应在其上执行注射的字段。 Mockito 将尝试仅通过构造器注入,设置器注入或属性注入按此顺序注入模拟。 如果任何给定的注射策略失败,则 Mockito 不会报告失败。 > 阅读更多: [`@Mock`和`@InitMock`注解之间的区别](https://howtodoinjava.com/mockito/mockito-mock-initMock/) ## 2\. 如何初始化 Mockito 注解 为了使用上述注解,测试类应使用以下三种给定方法之一初始化注解: 1. 在单元测试课的顶部使用`@RunWith(MockitoJUnitRunner.class)`。 ```java @RunWith(MockitoJUnitRunner.class) public class ExampleTest { @Mock private List list; @Test public void shouldDoSomething() { list.add(100); } } ``` 2. 在单元测试类的`@Before`方法中使用`MockitoAnnotations.initMock(this)`。 ```java public class ExampleTest { @Mock private List list; @Before public void setup() { MockitoAnnotations.initMock(this); } @Test public void shouldDoSomething() { list.add(100); } } ``` 3. 使用`MockitoJUnit.rule()`创建`MockitoRule`类。 ```java public class ExampleTest { @Rule public MockitoRule rule = MockitoJUnit.rule(); @Mock private List list; @Test public void shouldDoSomething() { list.add(100); } } ``` 在评论中,将您与 Mockito 注解有关的问题放到我这里。 学习愉快! 参考文献: [`Mock` Java Doc](https://static.javadoc.io/org.mockito/mockito-core/2.23.4/org/mockito/Mock.html) [`Spy` Java Doc](https://static.javadoc.io/org.mockito/mockito-core/2.23.4/org/mockito/Spy.html) [`Captor` Java Doc](https://static.javadoc.io/org.mockito/mockito-core/2.23.4/org/mockito/Captor.html) [`InjectMock` Java Doc](https://static.javadoc.io/org.mockito/mockito-core/2.23.4/org/mockito/InjectMock.html)