如何验证CancelOrderService执行时AvailableOptions.calculateAmount被调用一次
解决Mockito静态方法校验失败问题
问题分析
你的测试代码存在几个关键错误,导致静态方法调用未被捕获:
- 静态mock时机错误:
service.generateCancelOrder()调用在MockedStatic块外部,此时静态方法未被mock,实际执行的是真实方法,mock对象捕获不到交互。 - 校验对象错误:verify时调用了实例
availableOptions.calculateAmount(),但你mock的是AvailableOptions类的静态方法,应该直接调用类的静态方法。 - 参数匹配过严:存根时用
AvailableOptions.builder().build()作为参数,实际代码传入的实例大概率和这个不匹配,导致存根不生效。 - 冗余校验代码:try块外重复的
verifyNoMoreInteractions(cancelOrderService)位置错误且无意义。
修正后的测试代码
@Test public void service_called() { CurrentOrderState currentState = currentOrderState(ORDER_REF); TransactionData transactionData = transactionData(); ContractDetails contractDetails = contractDetails(); Source source = source(); // 用MockedStatic块包裹目标方法调用,确保静态mock生效 try (MockedStatic<AvailableOptions> availableOptionsMockedStatic = Mockito.mockStatic(AvailableOptions.class)) { // 存根静态方法,用any匹配参数避免实例不匹配 availableOptionsMockedStatic.when(() -> AvailableOptions.calculateAmount(any(AvailableOptions.class))) .thenReturn(""); // 在mock生效范围内调用目标业务方法 service.generateCancelOrder(currentState, source, transactionData, contractDetails); // 校验静态方法被调用一次,注意调用类的静态方法 availableOptionsMockedStatic.verify( () -> AvailableOptions.calculateAmount(any(AvailableOptions.class)), times(1) ); } // 校验cancelOrderService的调用逻辑 verify(cancelOrderService, times(1)).requestCancelOrder(any(IContext.class)); verifyNoMoreInteractions(cancelOrderService); }
关键修改说明
- 调整mock范围:把
service.generateCancelOrder()移到MockedStatic块内部,确保静态方法mock在业务方法执行时处于生效状态,这样mock才能捕获到调用。 - 统一静态方法调用:存根和校验时都使用
AvailableOptions.calculateAmount()(类的静态方法),而非实例方法,符合静态mock的逻辑。 - 宽松参数匹配:用
any(AvailableOptions.class)匹配参数,避免因实例对象不一致导致的存根失效或校验失败。 - 整理校验逻辑:将
cancelOrderService的校验移到静态mock块外,让代码逻辑更清晰,避免重复校验。
内容的提问来源于stack exchange,提问作者runnerpaul
相关产品推荐
相关产品推荐

