1

我正在模拟中创建一个自定义参数匹配器。使用这个例子:

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

这让我想知道为什么参数的类型listObject而不是List. 传递给 match 函数的参数可以是别的吗?如果是这样,示例是否不应该检查参数的类型并false在不是时返回List

稍微改述一下这个问题:mockito 是否承诺只将正确的类型传递给matches函数?如果是这样,为什么不使用泛型类型。如果不是,如果传递了错误的类型,为什么示例不返回 false?

4

2 回答 2

3
  • 如果您 extend ArgumentMatcher,您将收到一个对象,并且您有责任强制转换它。Mockito 将根据类名对其进行描述。
  • 如果您 extend BaseMatcher,您将收到一个对象,并且您有责任强制转换它。描述只会说明匹配器通过了什么,而不是它所期望的。
  • 如果您使用TypeSafeMatcher,您将收到您选择的类型的对象,并且您有责任描述它。它将为您检查非空性和类类型,并在类不匹配时提供合理的错误消息。

不要担心在你的匹配器中做出糟糕的演员表。Mockito 在验证调用匹配中将对其验证的调用包装在一个非常慷慨的 try/catch 块中,因此 ClassCastException 无论如何都会返回 false(或匹配失败)。


那么,为什么接口Matcher接受的比它的类型参数所允许的更多呢?

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

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

于 2012-10-25T20:55:06.967 回答
1

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

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

请注意,该ArgumentCaptor方法现在被推荐用于复杂的断言,例如,您可以在其中使用 AssertJ(FEST-Assert 的维护克隆)。

于 2012-10-25T10:12:43.390 回答