Mockito单元测试:能否验证Mock输入参数的方法副作用?
用Mockito实现带状态的Mock对象验证
当然可以用Mockito实现带状态的Mock对象,无需自行实现Rules接口,下面提供两种常用方案:
方案一:通过Answer自定义行为维护状态
利用Mockito的Answer接口(或lambda表达式),在Mock对象的register方法被调用时手动更新状态变量,后续直接验证该变量的变化即可。
示例代码:
@Mock Rules rules; // 用于存储状态的变量,根据实际需求定义类型 private String registeredParam; @Test void testRoutingStateChange() { MyClass testCase = new MyClass(); // 自定义register方法的执行逻辑:记录传入的参数作为状态 doAnswer(invocation -> { // 获取register方法的第一个入参(根据实际方法签名调整索引) registeredParam = invocation.getArgument(0); return null; // register是void方法,返回null }).when(rules).register(anyString()); // 匹配任意String类型参数,按需调整 // 调用待测的routing方法 testCase.routing(rules); // 验证状态是否符合预期 assertEquals("预期的参数值", registeredParam); }
如果需要处理多次调用的状态累积(比如多次调用register),可以用集合类维护状态:
private List<String> registeredParams = new ArrayList<>(); @Test void testMultipleRegisterCalls() { doAnswer(invocation -> { String param = invocation.getArgument(0); registeredParams.add(param); return null; }).when(rules).register(anyString()); MyClass testCase = new MyClass(); testCase.routing(rules); // 假设该方法会多次调用register // 验证状态累积结果 assertEquals(2, registeredParams.size()); assertTrue(registeredParams.contains("参数A")); assertTrue(registeredParams.contains("参数B")); }
方案二:用ArgumentCaptor捕获调用参数验证状态
如果你的“状态变化”本质是register方法被调用时传入了特定参数,那么可以用Mockito的ArgumentCaptor直接捕获调用时的参数,以此验证状态变化。
示例代码:
@Mock Rules rules; @Test void testRoutingWithArgumentCaptor() { MyClass testCase = new MyClass(); // 创建参数捕获器,类型与register方法的入参一致 ArgumentCaptor<String> paramCaptor = ArgumentCaptor.forClass(String.class); // 调用待测方法 testCase.routing(rules); // 捕获register方法的调用参数,并验证方法确实被调用 verify(rules).register(paramCaptor.capture()); // 验证捕获到的参数是否符合预期 assertEquals("预期的参数值", paramCaptor.getValue()); }
如果需要捕获多次调用的参数,直接用getAllValues()即可:
// 捕获后获取所有调用的参数列表 List<String> allParams = paramCaptor.getAllValues(); assertEquals(2, allParams.size());
内容的提问来源于stack exchange,提问作者R...
相关产品推荐
相关产品推荐

