使用Mockito 2时,应该使用ArgumentMarchers.any()
代替更具体的匹配器,例如ArgumentMatchers.anyString()
或ArgumentMatchers.anyList()
吗?是否应该使用特定的匹配器来使代码更具可读性?
根据经验,当使用原生对象(int
,long
,double
,boolean
)时,特定匹配器anyInt()
,anyLong()
, anyDouble()
或anyBoolean()
是首选。但其他匹配器呢?有任何想法吗?感谢。
答案 0 :(得分:4)
简而言之,在大多数情况下(尤其是Java 8或更新版本),您可以使用任何一种方法。虽然使用ngStyle
或any()
有一些实用的原因和一些正确性原因,anyString
对于非脆弱的Mockito测试通常更为惯用。注意:完整的基本原理深入研究了Mockito匹配器内部,Java类型参数推断以及大量hysterical raisins。
对于像any(String.class)
这样的原语,有一个非常实际的理由来选择anyFloat()
等而不是anyFloat()
:后者会给你一个NullPointerException。对于像any()
这样的Mockito语法,Mockito实际上会调用您的模拟when(floatAcceptor.acceptFloat(any())).then(/*...*/)
方法,并且调用floatAcceptor.acceptFloat(float)
必须返回any()
because Mockito matchers have to return a dummy value而Java不告诉Mockito足以让它知道返回null
兼容的值。无论Mockito如何,Java都会尝试将float
取消装入null
并失败。
(float
和anyFloat()
tell Mockito to expect a float
,因此他们正确返回any(Float.class)
。)如果您知道某个值是基元,盒装或未装箱,则更安全地调用适当的方法。
这个原因消失了0.0f
和List
,它们是通过和通过的对象; Java很乐意传递从String
收到的null
。
从历史上看,any
的行为与any
,any(Class)
和anyString()
相同;这是一个重要的便利,因为Java 7无法从参数推断出类型参数,因此备选方案是anyList(Class)
或(Foo) any()
。与那些相比,ArgumentMatchers.<Foo>any()
更具可读性。列表更糟糕,因为类型文字不支持其他类型,因此any(Foo.class)
甚至不适用于any(List.class)
;您需要List<Bar>
或(List<Bar>) any()
,但使用ArgumentMatchers.<List<Bar>>any()
,您只需撰写anyList
即可。在所有情况下,参数都被完全忽略,要检查类型,您需要使用anyList(Bar.class)
进行反思,isA(Class)
- 拒绝,null
- 样式检查。
但是,发生了两项改进:Java 8 happily infers type arguments through parameters,因此instanceof
更有用,而Mockito corrected its syntax看起来更像英语。在英语中,“任何汽车”都不太可能包括自行车或空车位,但在Mockito中1.x any()
会很乐意将调用与any(Car.class)
或null
实例匹配。因此,在Mockito 2.x中,Bicycle
和any(String)
只会接受非anyString()
字符串,as documented in GitHub issue #185。与所有其他null
电话相同。
最重要的是,Mockito更喜欢灵活的测试,而不是脆弱的测试,因此您更有可能看到any(Class)
与[{1}}或{{1}无关的any()
参数}}。按惯例忽略不相关的参数,如果更改它们不太可能影响正在测试的行为。也就是说,当您知道参数不是Foo
时,isA(Foo.class)
和eq(new Foo())
对于可读性非常有用,并且如果您的参数不能编译,也可以帮助您跟踪长参数列表列出与您正在调用的方法不兼容的方式更改。
总结如下:使用基元的基本方法,尽可能使用anyString()
,但切换到anyList()
,null
或{{1如果你想检查非any()
类型是否正确,如果你想提高可读性,或者你需要维护长期频繁变化的参数列表。
您可以在this GitHub issues answer上详细了解any(Class)
,any(List)
和any(String)
的语义。