argumentcaptor 用于捕获方法调用时传入的参数值,适用于验证非基本类型或复杂对象是否按预期传递,尤其在需检查对象字段、处理含动态值对象或对参数进一步断言时使用。

ArgumentCaptor 是 Mockito 提供的工具,用于**捕获方法调用时传入的参数值**,特别适合验证被测代码是否向依赖对象传递了预期的对象(尤其是非基本类型或复杂对象),而不需要断言整个对象的每个字段。
什么时候需要用 ArgumentCaptor
当你想检查:
- 某个 mock 对象的方法被调用时,传进去的是不是你期望的那个对象(比如新建的 User 实例、封装的 DTO、自定义回调等);
- 参数是引用类型且无法直接用 equals() 精确比对(例如含时间戳、随机 ID 的对象);
- 需要进一步对捕获到的参数做断言(如检查某个字段值、调用其方法)。
基本用法三步走
1. 声明 captor(推荐使用 @Captor 注解)
在测试类中声明并用 @Captor 标记:
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepository;
<pre class="brush:java;toolbar:false;">@Captor
private ArgumentCaptor<User> userCaptor; // 捕获 User 类型参数
@Test
void shouldSaveNewUser() {
// ...
}}
2. 在 verify 时使用 captor.capture()
在 verify(mock).method(...) 中,把 captor.capture() 当作参数传入:
userService.createUser("Alice", 25);
verify(userRepository).save(userCaptor.capture());3. 获取并断言捕获的参数
调用 captor.getValue()(单次调用)或 captor.getAllValues()(多次调用):
User capturedUser = userCaptor.getValue();
assertThat(capturedUser.getName()).isEqualTo("Alice");
assertThat(capturedUser.getAge()).isEqualTo(25);处理多次调用和集合参数
如果被验证的方法被调用了多次,用 getAllValues() 获取 List:
-
userCaptor.getAllValues()返回List<user></user>,可按索引取值或遍历断言 - 配合
verify(mock, times(2)).method(...)更稳妥 - 若参数是集合(如
List<string></string>),captor 类型写成ArgumentCaptor<list>></list>,注意泛型擦除不影响捕获
注意事项和常见坑
- 不要在
when(...).thenReturn(...)中用 captor —— 它只用于verify - captor 捕获的是“实际传入的引用”,不是副本,修改它可能影响原逻辑(但测试中一般只读)
- 如果参数是 null,
getValue()返回 null,需先用verify确保方法确实被调用过 - 避免过度使用:简单值(如字符串、数字)直接用
verify(mock).method("expected")更清晰
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











