Mockito ArgumentCaptor完全指南:掌握@Captor注解的使用方法与实例
Mockito的ArgumentCaptor(参数捕获器)用于捕获模拟方法中的参数。ArgumentCaptor与Mockito的verify()方法结合使用,可以获取调用任何方法时传递的参数值。这样,我们能够在测试中添加额外的JUnit断言。
模拟参数捕获器
我们可以为任何类创建ArgumentCaptor实例,然后使用其capture()方法与verify()方法一起使用。最后,我们可以通过getValue()和getAllValues()方法获取捕获的参数。当只捕获了一个参数时,可以使用getValue()方法。如果被验证的方法被多次调用,getValue()方法将返回最新捕获的值。如果捕获了多个参数,则应调用getAllValues()方法获取参数列表。
Mockito参数捕获器示例
假设我们有一个定义如下的类:
class MathUtils {
public int add(int x, int y) {
return x + y;
}
public boolean isInteger(String s) {
try {
Integer.parseInt(s);
} catch (NumberFormatException e) {
return false;
}
return true;
}
public long squareLong(long l) {
return l*l;
}
}
我们可以根据以下示例编写测试用例,并使用ArgumentCaptor。
@Test
void test() {
MathUtils mockMathUtils = mock(MathUtils.class);
when(mockMathUtils.add(1, 1)).thenReturn(2);
when(mockMathUtils.isInteger(anyString())).thenReturn(true);
ArgumentCaptor acInteger = ArgumentCaptor.forClass(Integer.class);
ArgumentCaptor acString = ArgumentCaptor.forClass(String.class);
assertEquals(2, mockMathUtils.add(1, 1));
assertTrue(mockMathUtils.isInteger("1"));
assertTrue(mockMathUtils.isInteger("999"));
verify(mockMathUtils).add(acInteger.capture(), acInteger.capture());
List allValues = acInteger.getAllValues();
assertEquals(List.of(1, 1), allValues);
verify(mockMathUtils, times(2)).isInteger(acString.capture());
List allStringValues = acString.getAllValues();
assertEquals(List.of("1", "999"), allStringValues);
}
使用 @Captor 注解
我们可以使用@Captor注解在字段级别创建参数捕获器。因此,不需要像之前那样手动初始化字段级别的ArgumentCaptor:
ArgumentCaptor acLong = ArgumentCaptor.forClass(Long.class);
我们可以将 @Captor 用作:
@Captor ArgumentCaptor acLong;
请注意,在测试方法执行之前,我们必须调用MockitoAnnotations.initMocks(this)来通过Mockito框架进行初始化。
Mockito的@Captor使用示例
下面是一个@Captor注解的简单示例。
class MockitoArgumentCaptorExamples {
@Captor ArgumentCaptor acLong;
@Test
void test() {
MathUtils mockMathUtils = mock(MathUtils.class);
when(mockMathUtils.squareLong(2L)).thenReturn(4L);
assertEquals(4L, mockMathUtils.squareLong(2L));
verify(mockMathUtils).squareLong(acLong.capture());
assertTrue(2 == acLong.getValue());
}
}
你可以从我们的GitHub存储库中查看完整的代码和更多的Mockito示例。