ArgumentMatchers.any()与Mockito 2中的其他匹配器

时间:2017-05-31 14:35:06

标签: java unit-testing mockito

使用Mockito 2时,应该使用ArgumentMarchers.any()代替更具体的匹配器,例如ArgumentMatchers.anyString()ArgumentMatchers.anyList()吗?是否应该使用特定的匹配器来使代码更具可读性?

根据经验,当使用原生对象(intlongdoubleboolean)时,特定匹配器anyInt()anyLong()anyDouble()anyBoolean()是首选。但其他匹配器呢?有任何想法吗?感谢。

1 个答案:

答案 0 :(得分:4)

简而言之,在大多数情况下(尤其是Java 8或更新版本),您可以使用任何一种方法。虽然使用ngStyleany()有一些实用的原因和一些正确性原因,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并失败。  (floatanyFloat() tell Mockito to expect a float,因此他们正确返回any(Float.class)。)如果您知道某个值是基元,盒装或未装箱,则更安全地调用适当的方法。 这个原因消失了0.0fList,它们是通过和通过的对象; Java很乐意传递从String收到的null

从历史上看,any的行为与anyany(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中,Bicycleany(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)的语义。