ArgumentCaptor用于捕获mock方法调用的实际参数,适用于需对复杂、动态或未构造完成的参数做细致断言的场景;通过@Captor声明、verify内capture()、getValue()获取并校验。

ArgumentCaptor 是 Mockito 提供的工具类,用于在单元测试中捕获被模拟对象(mock)方法调用时传入的实际参数,特别适合验证方法是否以预期值被调用,尤其当参数是复杂对象、匿名内部类或构造过程较重时。
什么时候需要用 ArgumentCaptor
当你想断言某个 mock 方法被调用时传入的参数内容,但又不方便直接用 verify(mock).method(expectedObj)(比如期望对象需部分匹配、含动态字段、或尚未构造好),这时就该用 ArgumentCaptor 捕获实际传入的参数再做细致校验。
基本使用步骤
- 用
@Captor注解声明一个ArgumentCaptor<T>字段(T 是你要捕获的参数类型) - 在测试方法中调用
captor.capture()—— 这一步通常放在verify()内部 - 通过
captor.getValue()获取最后一次调用的参数,或captor.getAllValues()获取全部(多次调用时) - 对捕获到的对象进行断言,比如检查字段值、调用方法、或用 AssertJ / Hamcrest 做深度比较
完整示例(验证 service 调用 repository 时传入的 User 对象)
假设你有如下代码:public class UserService {<br> private final UserRepository repo;<br> public UserService(UserRepository repo) { this.repo = repo; }<br> public void createUser(String name, int age) {<br> User user = new User(name, age, LocalDateTime.now());<br> repo.save(user);<br> }<br>}
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
测试写法:
立即学习“Java免费学习笔记(深入)”;
// 使用 @ExtendWith(MockitoExtension.class) 或 @RunWith(MockitoJUnitRunner.class)@Mock<br>UserRepository repo;<br><br>@InjectMocks<br>UserService service;<br><br>@Captor<br>ArgumentCaptor<User> userCaptor;<br><br>@Test<br>void shouldSaveUserWithCorrectNameAndAge() {<br> // 执行业务逻辑<br> service.createUser("Alice", 25);<br><br> // 捕获参数并验证<br> verify(repo).save(userCaptor.capture());<br> User captured = userCaptor.getValue();<br> assertEquals("Alice", captured.getName());<br> assertEquals(25, captured.getAge());<br> assertNotNull(captured.getCreatedAt()); // 可进一步断言时间合理性<br>}
注意点和常见坑
-
@Captor字段必须与@Mock/@InjectMocks一样,由 Mockito 测试运行器初始化;若手动 new Captor,会报 NPE - 一个
ArgumentCaptor只能捕获一种类型参数;多个不同参数类型需分别声明多个 captor - 如果方法有多个同类型参数(如
save(User u1, User u2)),需用captor.getAllValues()并按顺序取值,或改用verify(...).method(argThat(...))更清晰 - 避免在 verify 外调用
captor.capture()—— 它不是“监听器”,只在 verify 匹配时才生效

















