Mockito 模拟 when() 两种不同类型的泛型方法

Ric*_*rdK 5 java generics mockito

我有两个类的通用对象Generic<T, R>

Generic<TypeA, TypeB> genericOne;
Generic<TypeB, TypeC> genericTwo;
Run Code Online (Sandbox Code Playgroud)

我必须嘲笑:

when(someObject.someMethod(Matchers.<Generic<TypeA, TypeB>>any()))
                .thenReturn(responseOne());

when(someObject.someMethod(Matchers.<Generic<TypeB, TypeC>>any()))
                .thenReturn(responseTwo());
Run Code Online (Sandbox Code Playgroud)

问题是,由于类型擦除,mockito 不会看到这两个方法调用之间的区别——它都被识别为Generic<T, R>类。

有什么办法可以区分这两种方法调用吗?

dav*_*xxx 3

Mockito 不知道在调用之前指定了哪些泛型any(),无论如何这并不重要。

记录模拟行为所需的参数必须依赖于:

  • 值(就equals()
  • 或者就俘虏而言,如果equals()还不够的话
  • 或者any()如果模拟调用中的参数值无关紧要或者在测试装置中未知

这些永远不必依赖于泛型指定。

要获得一个好的示例,请查看Mockito.anyCollectionOf(Class<T> clazz)Mockito.anyMapOf(Class<K> keyClazz, Class<V> valueClazz)

这些方法知道类已通过,但无论如何,它们的规范指出:

此方法不执行任何类型检查,它只是为了避免在代码中进行强制转换。然而,这可能会在未来的主要版本中发生变化(可以添加类型检查)。

一般来说,您要检查的是要模拟的方法是使用预期参数而不是任何参数调用的:因此any()永远不会实现它。
因此,尝试仅检查泛型类型但接受任何值作为参数似乎是一种反模式模拟。

在您的情况下,如果equals()不方便在when()记录中进行匹配,请使用 Mockito captor 并verify()在执行模拟后进行检查。