Mockito mock SLF4J Logger接口时方法调用验证失败是什么原因?
问题根本原因
这是SLF4J Logger 接口的方法重载和Mockito匹配逻辑不一致导致的:
SLF4J的Logger为日志方法提供了多套重载,和本次问题相关的两个重载是:
void debug(String format, Object arg1, Object arg2)void debug(String format, Object... arguments)
你的业务代码中调用log.debug(format, arguments)时,arguments本身是Object[]类型,所以实际调用的是可变参数的重载方法debug(String, Object...)。
而测试代码里写的verify(logger).debug("some message", "arg1", "arg2")传入了3个独立参数,Mockito会尝试匹配双参数的重载方法debug(String, Object, Object)。
二者命中的不是同一个方法签名,自然验证失败。错误日志里会自动把可变参数展开打印,所以才会看起来两次调用的参数完全一致,产生误导。
修复方案
修改测试的verify逻辑,明确匹配可变参数重载即可,两种常用写法:
- 手动封装参数为数组:
verify(logger).debug(eq("some message"), (Object) new Object[]{"arg1", "arg2"});
- 用Mockito参数匹配器做严格校验:
// 严格匹配可变参数内容 verify(logger).debug(eq("some message"), aryEq(new Object[]{"arg1", "arg2"})); // 只校验格式、不校验参数内容的简化写法 verify(logger).debug(eq("some message"), any(Object[].class));
额外优化提示
你当前的测试代码里同时使用了@Mock注解和mock()方法手动初始化Mock对象,属于重复操作,任选其一保留即可:要么保留@Mock注解,删除setup方法里的trebuchetClient = mock(...)和logger = mock(...);要么删除类上的@Mock注解,保留手动初始化逻辑。
内容的提问来源于stack exchange,提问作者oibe
相关产品推荐
相关产品推荐

