使用Mockito 2,是否应该使用ArgumentMarchers.any()
代替更具体的匹配器,例如ArgumentMatchers.anyString()
或ArgumentMatchers.anyList()
?应该使用特定的匹配器使代码更可读吗?
从经验中,当使用本机objets(int
,long
,double
,boolean
(时,优先选择了特定的匹配器anyInt()
,anyLong()
,anyDouble()
或anyBoolean()
。但是其他匹配者呢?有任何想法吗?谢谢。
简而言之,您可以在大多数情况下使用一个(尤其是在Java 8或更新的情况下(。any()
通常对非脆弱的莫科托测试更为惯用,尽管有一些务实的原因和一些使用anyString
或any(String.class)
的正确性原因。当心:完整的基本原理深入研究Mockito Matcher内部,Java类型参数推理和许多歇斯底里的葡萄干。
对于诸如anyFloat()
之类的原始词,有一个非常实际的理由更喜欢anyFloat()
等而不是any()
:后者将为您提供NullPoInterException。对于诸如when(floatAcceptor.acceptFloat(any())).then(/*...*/)
之类的Mockito语法,Mockito实际上会调用您模拟的floatAcceptor.acceptFloat(float)
方法,并且呼叫any()
必须返回null
,因为Mockito Matchers必须返回虚拟值,Java并不足够告诉Mockito,以至于它不足。不管莫科托(Mockito(如何,Java都会尝试将null
拆分为float
并失败。 (anyFloat()
和any(Float.class)
告诉Mockito期望float
,因此他们正确返回0.0f
。(如果您知道一个值是原始的,盒装的或未包装的,则调用适当的方法。> >对于List
和String
的原因,这些原因消失了,它们是整个对象。Java将愉快地通过null
收到的CC_31。
从历史上看,any
的行为与any(Class)
,anyString()
和anyList(Class)
相同。这是一个重要的便利性,因为Java 7无法从参数中推断出类型的参数,因此替代方法是(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
-拒绝,instanceof
-式检查。
然而,发生了两次改进,这改变了这一点:Java 8愉快地通过参数输入类型参数,因此any()
更有用,而Mockito更正了其语法,以看起来像英语更像英语。在英语中,"任何汽车"不太可能包括自行车或空停车位,但是在Mockito 1.X any(Car.class)
中,null
或CC_51或Bicycle
实例很乐意将调用匹配。因此,在Mockito 2.x中,any(String)
和anyString()
仅接受非null
字符串,如GitHub问题185中所述。与所有其他any(Class)
调用相同。
最重要的是,Mockito更喜欢灵活的测试而不是脆性测试,因此您比isA(Foo.class)
或eq(new Foo())
更有可能看到any()
的CC_57。如果更改它们不太可能影响所测试的行为,则忽略了无关的参数。也就是说,当您知道参数不是null
时,anyString()
和anyList()
对于可读性可能很有用,也可以通过不兼容的方式来帮助您跟踪长期参数列表,以跟踪长时间的参数列表。打电话。
因此,摘要:使用原始方法作为原始方法,尽可能多地使用any()
,但请切换到any(Class)
,any(List)
或any(String)
,如果您想检查非null
类型,如果您是正确的,如果您是正确的,想要提高可读性,或者您需要维护漫长的经常变化的参数列表。
您可以在此Github问题上了解有关any()
,any(Class)
和isA
的语义的更多信息。