Mockito 注解– @Mock,@Spy,@Captor,@InjectMock

Mockito 注解– @Mock@Spy@Captor@InjectMock

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

@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 注解

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

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

    @RunWith(MockitoJUnitRunner.class)
    public class ExampleTest {
    
        @Mock
        private List list;
    
        @Test
        public void shouldDoSomething() {
            list.add(100);
        }
    }
    
    
  2. 在单元测试类的@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);
        }
    }
    
    
  3. 使用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