使用ArgumentCaptor测试void方法参数变更失败求助
问题排查与解决方案
核心错误分析
你误用了ArgumentCaptor的用法:
ArgumentCaptor的作用是捕获Mock对象被调用时传入的参数,必须配合verify()方法完成验证与捕获操作。- 你当前直接调用真实对象
authValidationHelper的方法,既没有关联Mock对象,也没有执行verify()步骤,所以captor.getAllValues()返回空是必然的。 - 你的测试场景完全不需要
ArgumentCaptor:因为list是你自己创建并传入方法的,方法内部直接修改了这个List,直接检查List的内容即可完成断言。
正确测试方案(推荐)
直接断言传入的list的变化,代码修改如下:
@Test public void test_isAuthExpired_ExpiredAuth() throws ParseException { List<Error> list = new ArrayList<>(); String request = inputProvider.createValidCreateOrderRequest_1(); PaymentTriggerBaseModel baseModel = ParserUtil.getObjectFromString(request, PaymentTriggerBaseModel.class); authValidationHelper.isAuthExpired( baseModel.getPayment().getPaymentMethods().get(0), list ); // 直接断言list的内容 assertFalse(list.isEmpty()); assertEquals( String.valueOf(PaymentErrorCodes.AUTH_EXPIRED), list.get(0).getField() ); assertEquals( PaymentErrorCodes.AUTH_EXPIRED.getDescription(), list.get(0).getDescription() ); }
何时适合用ArgumentCaptor?
如果你的业务方法内部调用了某个Mock依赖对象的方法(比如errorService.addError(error)),此时可以用ArgumentCaptor捕获传给Mock对象的参数,示例如下:
1. 测试类定义Mock依赖
@Mock private ErrorService errorService; // 假设AuthValidationHelper依赖此服务 @InjectMocks private AuthValidationHelper authValidationHelper;
2. 修改业务方法(调用Mock服务)
public void isAuthExpired(PaymentMethod paymentMethod, List<Error> errorList) { PaymentDetails paymentDetails = paymentMethod.getPaymentDetails(); Date authExpirationTime = paymentDetails.getAuthorizationExpirationDate(); boolean isAuthExpired = new Date().after(authExpirationTime); log.info("START : isAuthExpired for requestId: {}", paymentDetails.getRequestId()); if (isAuthExpired) { log.info("START : validateOrderTotalAmount for result: {}", false); Error error = new Error( String.valueOf(PaymentErrorCodes.AUTH_EXPIRED), PaymentErrorCodes.AUTH_EXPIRED.getDescription() ); errorList.add(error); errorService.recordError(error); // 调用Mock对象的方法 } }
3. 测试代码用ArgumentCaptor捕获参数
@Test public void test_isAuthExpired_ExpiredAuth() throws ParseException { List<Error> list = new ArrayList<>(); String request = inputProvider.createValidCreateOrderRequest_1(); PaymentTriggerBaseModel baseModel = ParserUtil.getObjectFromString(request, PaymentTriggerBaseModel.class); authValidationHelper.isAuthExpired( baseModel.getPayment().getPaymentMethods().get(0), list ); ArgumentCaptor<Error> captor = ArgumentCaptor.forClass(Error.class); // 验证Mock方法被调用,并捕获传入的参数 verify(errorService).recordError(captor.capture()); Error capturedError = captor.getValue(); assertEquals( String.valueOf(PaymentErrorCodes.AUTH_EXPIRED), capturedError.getField() ); }
内容的提问来源于stack exchange,提问作者Loren
相关产品推荐
相关产品推荐

