能否使用ArgumentMatchers类型变量?修改Mockito桩代码是否具备等效效果?
能不能用ArgumentMatchers类型的变量?
直接说结论:这种写法行不通,而且完全没有意义,修改后的代码和原代码效果天差地别。
为什么不能这么写?
Mockito的any()、anyInt()这类ArgumentMatchers方法,本质上不是返回一个“匹配任意值”的变量——它们的工作逻辑是在when()方法的调用上下文里,向Mockito内部注册参数匹配规则。如果把它们赋值给变量,脱离了这个上下文:
- 对于引用类型(比如
byte[]),any()会返回null;对于基本类型int,anyInt()会返回0 - Mockito不会记录这个“匹配任意值”的规则,只会把变量里的
null/0当作普通的参数值来匹配
所以你修改后的代码:
byte[] array = any(); int index = anyInt(); when(some.some(array, index)).thenAnswer(i -> i.getArguments(0));
实际上等价于:
when(some.some(null, 0)).thenAnswer(i -> i.getArguments(0));
只会匹配参数为null和0的调用,而原代码when(some.some(any(), anyInt()))是匹配任意byte数组和任意int索引的调用,两者效果完全不同。
这种写法有意义吗?
完全没有。ArgumentMatchers的设计就是要直接写在when()(或者verify())的方法参数列表里,这样Mockito才能在正确的上下文里捕获匹配规则。把它们赋值给变量的操作,既破坏了匹配逻辑,又没有带来任何代码上的简洁性或复用性——反而会让代码逻辑变得混乱。
如果想复用匹配规则怎么办?
如果确实需要复用某个匹配逻辑,可以把匹配器封装成方法,比如:
private byte[] anyByteArray() { return any(byte[].class); } private int anyIndex() { return anyInt(); }
然后在when()里直接调用这些方法:
when(some.some(anyByteArray(), anyIndex())).thenAnswer(i -> i.getArguments(0));
这样既实现了复用,又能让Mockito正确捕获匹配规则,因为匹配器方法的调用还是发生在when()的上下文里。
内容的提问来源于stack exchange,提问作者Jin Kwon
相关产品推荐
相关产品推荐

