将哪些对象传递给Mockito中的自定义ArgumentMatcher

时间:2012-10-25 09:44:57

标签: java mockito

我正在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?

2 个答案:

答案 0 :(得分:3)

  • 如果你延长ArgumentMatcher,你将收到一个物品,你有责任施展它。 Mockito将根据班级名称对其进行描述。
  • 如果你延长BaseMatcher,你将收到一个物品,你有责任施展它。描述只会说明匹配器的内容,而不是预期的内容。
  • 如果您使用TypeSafeMatcher,您将收到所选类型的对象,您有责任对其进行描述。它将为您检查非nullity和类类型,并在类不匹配时提供合理的错误消息。

不要担心在匹配器中造成糟糕的演员表。 Mockito在verificationinvocation matching中的一个非常慷慨的try / catch块中包含对其验证的调用,因此无论如何ClassCastException将返回false(或无法匹配)。


接下来,为什么接口Matcher会接受比其类型参数更多的接受?

  

此方法与Object匹配,而不是泛型类型T.这是因为Matcher的调用者在运行时不知道该类型是什么(因为Java泛型的类型擦除)。这取决于检查正确类型的实现。

因此,换句话说,即使Matcher要进行参数化,也不会在运行时提供非常强大的类型安全检查。但是,在Mockito中,它非常有用 - argThat(Matcher<T>)返回T类型的值而不是Object,因此您不必每次使用argThat(...)在你的测试中。

答案 1 :(得分:1)

因为mockito匹配器使用Hamcrest匹配器,所以在您提供的javadoc链接中,您将看到它继承了接口matchesorg.hamcrest.Matcher的签名,该签名在实际界面中似乎不是通用的

如果编译器正确地完成了他的工作,你可以假设你将获得正确的类型。

请注意,现在建议使用ArgumentCaptor方法进行复杂断言,例如,您可以使用AssertJ(维护FEST-Assert的克隆)。