2017-05-31 23 views
0

其他匹配器利用的Mockito 2,應ArgumentMarchers.any()被用來代替像ArgumentMatchers.anyString()ArgumentMatchers.anyList()例如更具體的匹配?應該使用特定的匹配器來使代碼更易讀?ArgumentMatchers.any()與在2的Mockito

從經驗來看,使用本機OBJETS(intlongdoubleboolean),特定的匹配anyInt()anyLong()anyDouble()anyBoolean()優選時。但其他匹配器呢?有任何想法嗎?謝謝。

回答

2

總之,你可以在大多數情況下使用任何一種(特別是在Java 8或更新的版本中)。 any()通常對非脆性Mockito測試更具慣用,儘管有一些實用的原因和一些正確性原因使用anyStringany(String.class)。請注意:完整的基本原理深入研究了Mockito匹配器內部,Java類型參數推理以及大量的hysterical raisins


對於像anyFloat()元,還有一個非常實用的理由,更喜歡anyFloat()等,而不是any():後者會給你一個NullPointerException。對於Mockito語法,例如when(floatAcceptor.acceptFloat(any())).then(/*...*/),Mockito實際上會調用您的模擬floatAcceptor.acceptFloat(float)方法,並且調用any()必然會返回nullbecause Mockito matchers have to return a dummy value並且Java不會告訴Mockito足以知道返回float兼容值。無論Mockito如何,Java都會嘗試將null解壓到float並失敗。 (anyFloat()any(Float.class)tell Mockito to expect a float,因此它們正確地返回0.0f。)如果您知道某個值是原始的,裝箱的或未裝箱的,則調用適當的方法會更安全。 這個原因消失了ListString,這是通過和通過的對象; 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拒絕,instanceof式檢查的類型。

但是,發生了兩處改進:Java 8 happily infers type arguments through parameters,因此any()更易於使用,並且Mockito corrected its syntax看起來更像英語。在英語中,「任何汽車」不可能包括自行車或空的停車位,但在Mockito 1.x any(Car.class)將愉快地匹配nullBicycle實例的調用。因此,在Mockito 2.x中,any(String)anyString()將只接受非null字符串,as documented in GitHub issue #185。與所有其他any(Class)調用相同。

爲最糟糕的是,喜歡的Mockito靈活的測試,而不是那些脆,所以你更可能看到any()超過isA(Foo.class)eq(new Foo())無關Foo參數。按照約定忽略不相關的參數,如果改變它們不太可能影響被測試的行爲。也就是說,anyString()anyList()在知道參數不是null時可用於提高可讀性,還可以幫助您跟蹤長參數列表,如果列表以與您的方法不兼容的方式更改,則無法編譯呼叫。原語用原始的方法,使用any()儘可能的,但切換到any(Class)any(List)any(String)如果要檢查非null類型是正確的,如果你想提高可讀性:在總結

所以,或者你需要保持長時間變化的參數列表。

關於this GitHub issues answer,您可以閱讀關於any()any(Class)isA的語義的更多信息。