简体   繁体   English

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

[英]What objects will be passed to a custom ArgumentMatcher in Mockito

I am creating a custom argument matcher in mockito. 我正在mockito中创建一个自定义参数匹配器。 Using this example: 使用示例:

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

This made me wonder why the type of the parameter list is Object instead of List . 这让我想知道为什么参数list的类型是Object而不是List Can the argument passed to the match function be something else? 传递给匹配函数的参数可以是别的吗? And if so shouldn't the example check the type of the parameter and return false if it isn't a List ? 如果是这样,示例不应该检查参数的类型,如果它不是List ,则返回false

To rephrase the question a little: Does mockito promise to only pas the correct type to the matches function? 稍微改一下这个问题:mockito是否承诺只将正确的类型传递给matches函数? If so, why doesn't it use the generic type. 如果是这样,为什么不使用泛型类型。 And if not why doesn't the example return false if the wrong type is passed to it? 如果不是,为什么如果错误的类型传递给它,示例是否返回false?

  • If you extend ArgumentMatcher , you will receive an object, and it's your responsibility to cast it. 如果你扩展ArgumentMatcher ,你将收到一个对象,你有责任投射它。 Mockito will describe it based on the class name. Mockito将根据班级名称对其进行描述。
  • If you extend BaseMatcher , you will receive an object, and it's your responsibility to cast it. 如果你扩展BaseMatcher ,你将收到一个对象,你有责任投射它。 The description will only say what the matcher was passed, not what it was expecting. 描述只会说明匹配器的内容,而不是预期的内容。
  • If you use TypeSafeMatcher , you will receive an object of your chosen type, and it's your responsibility to describe it. 如果您使用TypeSafeMatcher ,您将收到所选类型的对象,您有责任对其进行描述。 It will check non-nullity and class type for you, and provide a sane error message if the class doesn't match. 它将为您检查非nullity和类类型,并在类不匹配时提供合理的错误消息。

Don't worry about making a bad cast in your matcher. 不要担心在匹配器中造成糟糕的演员表。 Mockito wraps calls to its verification within a very generous try/catch block in both verification and invocation matching so a ClassCastException will return false (or fail to match) anyway. Mockito在验证调用匹配中都在一个非常慷慨的try / catch块中调用验证 ,因此无论如何ClassCastException都将返回false(或无法匹配)。


Why, then, would interface Matcher accept more than its type parameter lets on? 那么,为什么接口Matcher接受比其类型参数更多的接受?

This method matches against Object, instead of the generic type T. This is because the caller of the Matcher does not know at runtime what the type is (because of type erasure with Java generics). 此方法与Object匹配,而不是泛型类型T.这是因为Matcher的调用者在运行时不知道类型是什么(因为Java泛型的类型擦除)。 It is down to the implementations to check the correct type. 这取决于检查正确类型的实现。

So, in other words, even if Matcher were to be parameterized it wouldn't provide a very strong type safety check at runtime. 因此,换句话说,即使Matcher被参数化,它也不会在运行时提供非常强大的类型安全检查。 However, in Mockito, it's very useful-- argThat(Matcher<T>) returns a value of type T instead of Object , so you don't have to cast every single use of argThat(...) in your tests. 但是,在Mockito中,它非常有用 - argThat(Matcher<T>)返回类型为T而不是Object的值,因此您不必在测试中每次使用argThat(...)

Because the mockito matchers use Hamcrest matchers, in the javadoc link you provided, you'll see that it inherits the signature of matches in interface org.hamcrest.Matcher which appear to not be generic in the actual interface. 因为mockito匹配器使用Hamcrest匹配器,所以在您提供的javadoc链接中,您将看到它继承了org.hamcrest.Matcher接口中matches的签名,这在实际接口中似乎不是通用的。

If the compiler has made his job correctly you can assume you'll get the correct type though. 如果编译器正确地完成了他的工作,你可以假设你将获得正确的类型。

Note that the ArgumentCaptor approach is now recommanded for complex assertions, where you can use AssertJ (maintained clone of FEST-Assert) for example. 请注意,现在建议使用ArgumentCaptor方法进行复杂断言,例如,您可以使用AssertJ(维护FEST-Assert克隆)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM