Mockito ArgumentCaptor校验无返回值,无法捕获Mock方法入参
解决Mockito ArgumentCaptor捕获不到参数的问题
我来帮你分析下问题所在,以及怎么修复:
问题根源
你的代码里有个容易被忽略的细节:虽然你在verify语句里用了匹配器(eq("test")和captor.capture()),但手动创建ArgumentCaptor的方式在某些场景下会因为Mockito的上下文处理逻辑导致捕获失败;另外,旧版本Mockito可能存在参数匹配的小bug,也会影响捕获结果。
还有个潜在的坑要注意:你的isEnabled方法用了status = status && preferenceManager.isEventEnabled(...)短路与运算,不过当前你存根返回true,所以两次调用都会执行,这个不是这次的问题,但后续修改逻辑时要留意。
修复方案
方案1:用@Captor注解替代手动创建ArgumentCaptor
@Captor是Mockito官方推荐的参数捕获器初始化方式,比手动创建更稳定,能避免上下文相关的捕获失败问题:
修改测试类如下:
@RunWith(JUnit4.class) class CombinedNotificationAdapterTest { private CombinedNotificationAdapter adapter; @Mock private NotificationPreferenceManager preferenceManager; // 用@Captor注解声明参数捕获器 @Captor private ArgumentCaptor<String> eventCaptor; @Before public void setUp() { MockitoAnnotations.initMocks(this); adapter = new CombinedNotificationAdapter(); } @Test public void testIsEnabled() { // 存根方法,确保调用时返回true when(preferenceManager.isEventEnabled(eq("test"), anyString())).thenReturn(true); // 调用待测试方法 Assert.assertTrue(adapter.isEnabled("test", preferenceManager)); // 验证调用次数并捕获参数 verify(preferenceManager, times(2)).isEventEnabled(eq("test"), eventCaptor.capture()); // 现在应该能获取到预期的参数列表 System.out.println(eventCaptor.getAllValues()); // 输出 [WATCHITM, BIDITEM] } }
方案2:调整手动创建Captor的匹配逻辑
如果你坚持手动创建ArgumentCaptor,可以确保verify语句的参数匹配逻辑完全统一(所有参数都用匹配器):
@Test public void testIsEnabled() { doReturn(true).when(preferenceManager).isEventEnabled(eq("test"), anyString()); Assert.assertTrue(adapter.isEnabled("test", preferenceManager)); ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class); // 确保所有参数都使用匹配器,避免混合写法导致的匹配异常 verify(preferenceManager, times(2)).isEventEnabled(eq("test"), captor.capture()); System.out.println(captor.getAllValues()); }
方案3:升级Mockito版本
你参考的文档里有2.6.9和2.28.2两个版本,旧版本的Mockito存在一些参数捕获的小bug,建议升级到2.28.2或更高版本,能解决不少兼容性问题。
验证修复效果
修改后运行测试,captor.getAllValues()应该会返回包含WATCHITM和BIDITEM的列表,符合你的预期。
内容的提问来源于stack exchange,提问作者Krish
相关产品推荐
相关产品推荐

