2012-10-25 77 views
1

我正在mockito中創建一個自定義參數匹配器。使用this例如:什麼對象將被傳遞給Mockito中的自定義ArgumentMatcher

class IsListOfTwoElements extends ArgumentMatcher<List> { 
    public boolean matches(Object list) { 
     return ((List) list).size() == 2; 
    } 
} 

這讓我不知道爲什麼參數list的類型是Object,而不是List。 傳遞給匹配函數的參數可以是別的嗎?如果是這樣的話不應該檢查參數的類型,並且如果它不是List則返回false

稍微改寫一下問題: mockito答應只將正確的類型傳遞給matches函數嗎?如果是這樣,爲什麼不使用泛型類型。如果不是,爲什麼不傳遞錯誤的類型傳遞給它的例子返回false?

回答

1

因爲mockito匹配器使用Hamcrest匹配器,所以在您提供的javadoc鏈接中,您會看到它在org.hamcrest.Matcher接口中繼承matches的簽名,該接口似乎在實際接口中不是通用的。

如果編譯器正確地完成了他的工作,你可以假設你會得到正確的類型。

請注意,ArgumentCaptor方法現在推薦用於複雜的斷言,例如,您可以使用AssertJ(維護的FEST-Assert的克隆)。

3
  • 如果你擴展ArgumentMatcher,你會收到一個對象,你有責任去施放它。 Mockito會根據類名來描述它。
  • 如果您擴展BaseMatcher,您將收到一個對象,這是您的責任。描述只會說匹配器通過的是什麼,而不是它期望的。
  • 如果您使用TypeSafeMatcher,您將收到您選擇類型的對象,並且您有責任對其進行描述。它會爲你檢查非nullity和類的類型,如果類不匹配,就會提供一個合理的錯誤信息。

不要擔心在匹配器中造成糟糕的演員陣容。 Mockito在verificationinvocation matching這兩個非常慷慨的try/catch塊中包裝調用驗證,所以ClassCastException將返回false(或無法匹配)。


那麼爲什麼接口Matcher接受的比它的類型參數多呢?

該方法匹配Object而不是泛型類型T.這是因爲Matcher的調用者在運行時不知道類型是什麼(因爲Java泛型的類型擦除)。這取決於檢查正確類型的實現。

所以,換句話說,即使匹配器被參數化,它也不會在運行時提供非常強大的類型安全檢查。但是,在Mockito中,它非常有用 - argThat(Matcher<T>)返回的值爲T而不是Object,因此您不必在測試中投入每次使用argThat(...)

相關問題