在此 Mockito 教程中,了解 Mockito 注解,例如@Mock
,@Spy
,@Captor
,@InjectMock
。 学习使用模仿注解为行为测试编写单元测试。
1. Mockito 注解
1.1 @Mock
@Mock
注解用于创建和注入模拟实例。 我们不创建真实的对象,而是要求模拟为类创建一个模拟。
@Mock
注解是Mockito.mock(classToMock)
的替代方法。 它们都达到相同的结果。 通常认为使用@Mock
是“清洁器”,因为我们没有用看起来都一样的样板分配填充测试。
使用@Mock
注解:
- 允许快速创建测试所需的对象。
- 最小化重复的模拟创建代码。
- 使测试类更具可读性。
- 由于使用字段名称来识别模拟,因此使验证错误更易于阅读。
在给定的示例中,我们模拟了HashMap
类。 在实际测试中,我们将模拟实际的应用类。 我们在映射中放置了一个键值对,然后验证了对模拟映射实例执行了方法调用。
@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。 我们还可以使用它的键取回添加到映射的值。 在模拟实例中是不可能的。
@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()
方法验证参数值。
@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
注解之间的区别
2. 如何初始化 Mockito 注解
为了使用上述注解,测试类应使用以下三种给定方法之一初始化注解:
在单元测试课的顶部使用
@RunWith(MockitoJUnitRunner.class)
。@RunWith(MockitoJUnitRunner.class)
public class ExampleTest {
@Mock
private List list;
@Test
public void shouldDoSomething() {
list.add(100);
}
}
在单元测试类的
@Before
方法中使用MockitoAnnotations.initMock(this)
。public class ExampleTest {
@Mock
private List list;
@Before
public void setup() {
MockitoAnnotations.initMock(this);
}
@Test
public void shouldDoSomething() {
list.add(100);
}
}
使用
MockitoJUnit.rule()
创建MockitoRule
类。public class ExampleTest {
@Rule
public MockitoRule rule = MockitoJUnit.rule();
@Mock
private List list;
@Test
public void shouldDoSomething() {
list.add(100);
}
}
在评论中,将您与 Mockito 注解有关的问题放到我这里。
学习愉快!
参考文献:
Mock
Java Doc
Spy
Java Doc
Captor
Java Doc
InjectMock
Java Doc