我正在mockito中创建一个自定义参数匹配器。使用this示例:
class IsListOfTwoElements extends ArgumentMatcher<List> {
public boolean matches(Object list) {
return ((List) list).size() == 2;
}
}
这让我想知道为什么参数list
的类型是Object
而不是List
。
传递给匹配函数的参数可以是别的吗?如果是这样,示例不应该检查参数的类型,如果它不是false
,则返回List
?
稍微改写一下这个问题:
mockito是否承诺只将正确的类型传递给matches
函数?如果是这样,为什么不使用泛型类型。如果没有,为什么如果错误的类型被传递给它,示例是否会返回false?
答案 0 :(得分:3)
ArgumentMatcher
,你将收到一个物品,你有责任施展它。 Mockito将根据班级名称对其进行描述。BaseMatcher
,你将收到一个物品,你有责任施展它。描述只会说明匹配器的内容,而不是预期的内容。TypeSafeMatcher
,您将收到所选类型的对象,您有责任对其进行描述。它将为您检查非nullity和类类型,并在类不匹配时提供合理的错误消息。不要担心在匹配器中造成糟糕的演员表。 Mockito在verification和invocation matching中的一个非常慷慨的try / catch块中包含对其验证的调用,因此无论如何ClassCastException将返回false(或无法匹配)。
接下来,为什么接口Matcher
会接受比其类型参数更多的接受?
此方法与Object匹配,而不是泛型类型T.这是因为Matcher的调用者在运行时不知道该类型是什么(因为Java泛型的类型擦除)。这取决于检查正确类型的实现。
因此,换句话说,即使Matcher要进行参数化,也不会在运行时提供非常强大的类型安全检查。但是,在Mockito中,它非常有用 - argThat(Matcher<T>)
返回T
类型的值而不是Object
,因此您不必每次使用argThat(...)
在你的测试中。
答案 1 :(得分:1)
因为mockito匹配器使用Hamcrest匹配器,所以在您提供的javadoc链接中,您将看到它继承了接口matches
中org.hamcrest.Matcher
的签名,该签名在实际界面中似乎不是通用的
如果编译器正确地完成了他的工作,你可以假设你将获得正确的类型。
请注意,现在建议使用ArgumentCaptor
方法进行复杂断言,例如,您可以使用AssertJ(维护FEST-Assert的克隆)。