Mockito mockito mocking() 用于两个不同类型的泛型方法



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

Generic<TypeA, TypeB> genericOne;
Generic<TypeB, TypeC> genericTwo;

我不得不嘲笑:

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

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

有没有办法区分这两个方法调用?

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

模拟行为记录中预期的参数必须依赖于:

  • 值(以equals()
  • )
  • 或者在俘虏方面,如果equals()不足
  • any()模拟调用中的参数值是否无关紧要或在测试装置中未知

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

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

这些方法知道传递的类,但无论如何,它们的规范声明:

此方法不做任何类型检查,它只是为了避免 在代码中强制转换。但是,这可能会改变(类型检查可能是 添加)在未来的主要版本中。

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

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

我认为不可能区分两者,因为泛型类型是粗化的。但是还有其他选择。

您可以将此调用耦合到特定顺序,这样即使 mockito 无法区分它们,它也会返回预期值。这是通过链接thenReturn方法来完成的。第一个调用返回responseOne(),第二个调用返回responseTwo()

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

但这不是最佳选择,因为如果您的实现发生变化,此测试将中断。所以这是第二种选择。

您可以为此对象实现自定义假货。以便您可以控制此实例的行为方式。例如。

class SomeObjectFake {
private final SomeResponse response;
public SomeObject(SomeResponse response) {
this.response = response;
}
public SomeResponse someMethod(Generic<TypeA, TypeB> arg) {
// Decide what to return
return response;
}
}

最新更新