Mockito 和 Hamcrest:如何验证 Collection 参数的调用?
我遇到了 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.
相关文章