問題描述
我遇到了 Mockito 和 Hamcrest 的泛型問題.
I'm running into a generics problem with Mockito and Hamcrest.
請假設如下界面:
public interface Service {
void perform(Collection<String> elements);
}
還有下面的測試片段:
Service service = mock(Service.class);
// ... perform business logic
verify(service).perform(Matchers.argThat(contains("a", "b")));
所以我想驗證我的業務邏輯是否真的使用包含a"和b"的集合來調用服務.
So I want to verify that my business logic actually called the service with a collection that contains "a" and "b" in that order.
但是contains(...)
的返回類型是Matcher
Matchers.argThat(...)
在我的情況下返回 Iterable<String>
,這自然不適用于所需集合
.
However, the return type of contains(...)
is Matcher<Iterable<? extends E>>
, so Matchers.argThat(...)
returns Iterable<String>
in my case, which naturally does not apply to the required Collection<String>
.
我知道我可以使用 Hamcrest hasItem and Mockito verify 中建議的參數捕獲器不一致,但我非常不想這樣做.
I know that I could use an argument captor as proposed in Hamcrest hasItem and Mockito verify inconsistency, but I would very much like not to.
任何建議!謝謝!
推薦答案
你可以寫
verify(service).perform((Collection<String>) Matchers.argThat(contains("a", "b")));
從編譯器的角度來看,這是將 Iterable<String>
轉換為 Collection
argThat
將返回 null
,因此可以在沒有 ClassCastException
的情況下將其傳遞給 perform
.重要的一點是,匹配器進入 Mockito 的內部參數結構進行驗證,這就是 argThat
所做的.
From the compiler's point of view, this is casting an Iterable<String>
to a Collection<String>
which is fine, because the latter is a subtype of the former. At run time, argThat
will return null
, so that can be passed to perform
without a ClassCastException
. The important point about it is that the matcher gets onto Mockito's internal structure of arguments for verification, which is what argThat
does.
這篇關于Mockito 和 Hamcrest:如何驗證 Collection 參數的調用?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!