原文: 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类。 在实际测试中,我们将模拟实际的应用类。 我们在映射中放置了一个键值对,然后验证了对模拟映射实例执行了方法调用。

  1. @Mock
  2. HashMap<String, Integer> mockHashMap;
  3. @Test
  4. public void saveTest()
  5. {
  6. mockHashMap.put("A", 1);
  7. Mockito.verify(mockHashMap, times(1)).put("A", 1);
  8. Mockito.verify(mockHashMap, times(0)).get("A");
  9. assertEquals(0, mockHashMap.size());
  10. }

1.2 @Spy

@Spy注解用于创建真实对象并监视该真实对象。 间谍程序可以帮助调用对象的所有常规方法,同时仍可以跟踪每次交互,就像使用模拟一样。

请注意,在给定的示例中,由于我们向其中添加了一个键值对,因此映射的大小如何保持为 1。 我们还可以使用它的键取回添加到映射的值。 在模拟实例中是不可能的。

  1. @Spy
  2. HashMap<String, Integer> hashMap;
  3. @Test
  4. public void saveTest()
  5. {
  6. hashMap.put("A", 10);
  7. Mockito.verify(hashMap, times(1)).put("A", 10);
  8. Mockito.verify(hashMap, times(0)).get("A");
  9. assertEquals(1, hashMap.size());
  10. assertEquals(new Integer(10), (Integer) hashMap.get("A"));
  11. }

@Mock@Spy之间的区别

使用@Mock时,mockito 将创建类的准系统的 shell 实例,完全可以跟踪与之的交互。 这不是真实的对象,也不维护其状态更改。

使用@Spy时,mockito 创建类的真实实例并跟踪与之的每次交互。 它保持状态更改。

1.3 @Captor

@Captor注解用于创建ArgumentCaptor实例,该实例用于捕获方法参数值进行进一步的声明。

请注意,mockito 使用参数类的equals()方法验证参数值。

  1. @Mock
  2. HashMap<String, Integer> hashMap;
  3. @Captor
  4. ArgumentCaptor<String> keyCaptor;
  5. @Captor
  6. ArgumentCaptor<Integer> valueCaptor;
  7. @Test
  8. public void saveTest()
  9. {
  10. hashMap.put("A", 10);
  11. Mockito.verify(hashMap).put(keyCaptor.capture(), valueCaptor.capture());
  12. assertEquals("A", keyCaptor.getValue());
  13. assertEquals(new Integer(10), valueCaptor.getValue());
  14. }

1.4 @InjectMock

在模拟中,我们需要创建要测试的类的对象,然后插入其依赖项(模拟)以完全测试行为。 为此,我们使用@InjectMock注解。

@InjectMock标记应在其上执行注射的字段。 Mockito 将尝试仅通过构造器注入,设置器注入或属性注入按此顺序注入模拟。 如果任何给定的注射策略失败,则 Mockito 不会报告失败。

阅读更多: @Mock@InitMock注解之间的区别

2. 如何初始化 Mockito 注解

为了使用上述注解,测试类应使用以下三种给定方法之一初始化注解:

  1. 在单元测试课的顶部使用@RunWith(MockitoJUnitRunner.class)

    1. @RunWith(MockitoJUnitRunner.class)
    2. public class ExampleTest {
    3. @Mock
    4. private List list;
    5. @Test
    6. public void shouldDoSomething() {
    7. list.add(100);
    8. }
    9. }
  1. 在单元测试类的@Before方法中使用MockitoAnnotations.initMock(this)

    1. public class ExampleTest {
    2. @Mock
    3. private List list;
    4. @Before
    5. public void setup() {
    6. MockitoAnnotations.initMock(this);
    7. }
    8. @Test
    9. public void shouldDoSomething() {
    10. list.add(100);
    11. }
    12. }
  1. 使用MockitoJUnit.rule()创建MockitoRule类。

    1. public class ExampleTest {
    2. @Rule
    3. public MockitoRule rule = MockitoJUnit.rule();
    4. @Mock
    5. private List list;
    6. @Test
    7. public void shouldDoSomething() {
    8. list.add(100);
    9. }
    10. }

在评论中,将您与 Mockito 注解有关的问题放到我这里。

学习愉快!

参考文献:

Mock Java Doc
Spy Java Doc
Captor Java Doc
InjectMock Java Doc