[英]ArgumentMatchers.any() versus the other matchers in Mockito 2
對於Mockito 2,是否應使用ArgumentMarchers.any()
代替例如ArgumentMatchers.anyString()
或ArgumentMatchers.anyList()
類的更特定的匹配器? 應該使用特定的匹配器使代碼更具可讀性嗎?
根據經驗,在使用本機objets( int
, long
, double
, boolean
)時, anyInt()
特定匹配器anyInt()
, anyLong()
, anyDouble()
或anyBoolean()
。 但是其他匹配器呢? 有任何想法嗎? 謝謝。
簡而言之,在大多數情況下(特別是在Java 8或更高版本中),您可以使用任何一種。 盡管有一些實用的原因和使用anyString
或any(String.class)
正確性原因, any()
對於非易碎的Mockito測試而言通常更為慣用。 當心:完整的原理深入研究了Mockito匹配器內部,Java類型參數推斷以及大量歇斯底里的葡萄干 。
對於諸如anyFloat()
類的基元,有一個非常實際的理由更喜歡anyFloat()
等而不是any()
:后者將為您提供NullPointerException。 對於when when(floatAcceptor.acceptFloat(any())).then(/*...*/)
類的Mockito語法,Mockito實際上會調用floatAcceptor.acceptFloat(float)
方法,並且對any()
調用必然返回null
因為Mockito匹配器必須返回一個虛擬值,而Java並沒有告訴Mockito足夠多的信息使其知道返回一個float
兼容的值。 無論Mockito如何,Java都會嘗試將null
拆箱到float
並失敗。 ( anyFloat()
和any(Float.class)
告訴Mockito期望有float
,因此它們正確返回0.0f
。) 如果您知道某個值是原始值,裝箱值或拆箱值,則調用適當的方法會更安全。 這個理由對於List
和String
,它們都是貫穿對象。 Java將愉快地傳遞從any
接收到的null
。
從歷史上看, 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
-rejecting, instanceof
-style檢查。
但是,發生了兩個改進,從而改變了這一點: Java 8通過參數高興地推斷出類型實參 ,因此any()
更加有用,而Mockito更正了其語法,使其看起來更像英語。 用英語,“任何汽車”都不太可能包括自行車或空的停車位,但是在Mockito 1.x中, any(Car.class)
會很高興地將調用與null
或Bicycle
實例匹配。 因此,在Mockito 2.x中, any(String)
和anyString()
將僅接受非null
字符串, 如GitHub Issue#185中所述 。 與所有其他any(Class)
調用相同。
最重要的是,Mockito更喜歡靈活的測試而不是脆弱的測試,因此與isA(Foo.class)
或eq(new Foo())
相比,與Foo
參數無關的您更有可能看到any()
eq(new Foo())
。 如果更改不大可能影響測試行為的參數,則習慣上會忽略不相關的參數。 就是說,當您知道參數不為null
時, anyString()
和anyList()
有助於提高可讀性,並且如果列表以與列表不兼容的方式更改,則無法編譯,從而可以幫助您跟蹤較長的參數列表。您正在調用的方法。
因此,總而言之:如果對原始類型使用原始方法,請盡可能使用any()
,但是如果要檢查非null
類型是否正確,請切換到any(Class)
, any(List)
或any(String)
您想提高可讀性,或者需要維護很長且經常更改的參數列表。
您可以在此GitHub問題answer上閱讀有關any()
, any(Class)
和isA
的語義的更多信息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.