2015-11-02 122 views
1

Mockito提供了許多像任何(),anyClass()等匹配器。Mockito匹配器|正確使用

人們可以辯論他們的用法。但是我覺得,當我們不關心輸入對象包含什麼時,只要它是預期的類,就應該使用匹配器。

我只想知道這個用法是否正確?如果沒有,使用它們的更好方法是什麼?

例如:

假設我們有一個測試,希望運行時異常,當一個方法被稱爲一些請求對象。由於我們在調用模擬時顯式拋出運行時異常,因此請求對象的內容是什麼並不重要。所以這個測試似乎合乎邏輯

@Test(expected = RunTimeException.class) 
public void testExceptionOccurs() { 
    when(mock.method(any(RequestObject.class))).thenThrow(new RuntimeException()); 

    mock.method(new RequestObject()); 
} 

這是正確的方法嗎?

回答

3

你說得對,允許給定類型的任何對象對於Matchers是一個很好的用法,而且你正確地調用了matcher,但是代碼沒有做你正在描述的內容。

在Mockito 1.x中,any(RequestObject.class)實際上不會檢查參數的類型。它的行爲與anyObject()相同,除了在Java 8之前,Java編譯器無法推斷指定爲參數的泛型類型。 而是使用isA(RequestObject.class)來檢查類型。


的Mockito的默認行爲是檢查使用equals(或==對於基本類型)參數平等特異性平等。我發現any(和anyInt等)是最有價值的,因爲他們完全忽略了匹配的目的的說法,但也有很多的,你會希望覆蓋equals行爲與匹配器的原因:

  • 僅使用isA來檢查參數的類型。
  • 要檢查比equals更具體的實例,例如檢查引用相等性使用same
  • 要檢查參數的屬性,例如傳遞的bean對其某個屬性具有特定值。
  • 要通過intThatargThat等重用Hamcrest匹配器。

最後一點:確保如果您使用的匹配或俘虜在任何地方你的參數列表,您使用爲每個在該呼叫每次爭論。Mockito needs that 1:1 mapping.


UPDATE:的Mockito提交者Brice提供了some historical background and future direction

由於歷史的參考,anyanything速記別名,當時的API被強迫一個投,和貢獻者和/或委託人考慮將該類作爲參數傳遞以避免此類轉換,而不會更改此API的語義。然而,這種改變最終改變了人們認爲這個API正在做的事情。 這將被修復在mockito 2+

+0

總是使用'isA'而不是'any'更好嗎? – Templar

+0

@Templar絕對不是「永遠」:'isA' [拒絕null](https://github.com/mockito/mockito/blob/master/src/main/java/org/mockito/internal/matchers/InstanceOf.java #L22),這可能並非必要或不可取。更重要的是,Mockito語法默認支持靈活性,以減少響應重構和其他更改的測試脆弱性;參數值通常不太可能具有_relevant類型,而是不相關的值(其中'any'將覆蓋完全不相關的參數,而其他匹配器將覆蓋相關值)。 –