一个奇怪的泛型边缘情况与Mockito.when()和泛型类型推断

时间:2012-06-08 16:26:09

标签: java generics mockito

我正在编写一个使用Mockito java.beans.PropertyDescriptor的测试用例,我想模仿getPropertyType()的行为来返回任意Class<?>对象(在我的情况下,{ {1}})。通常,我会通过调用:

来做到这一点
String.class

然而,奇怪的是,这不会编译:

// we already did an "import static org.mockito.Mockito.*"
when(mockDescriptor.getPropertyType()).thenReturn(String.class);

但是当我指定类型参数而不是依赖于推理时:

cannot find symbol method thenReturn(java.lang.Class<java.lang.String>)
一切都是笨拙的。为什么编译器在这种情况下无法正确推断when()的返回类型?我之前从未必须指定参数。

1 个答案:

答案 0 :(得分:13)

PropertyDescriptor#getPropertyType()返回Class<?>的对象,其中?表示“这是一种类型,但我不知道它是什么”。我们称这种类型为“X”。因此when(mockDescriptor.getPropertyType())会创建OngoingStubbing<Class<X>>,其方法thenReturn(Class<X>)只能接受Class<X>的对象。但是编译器不知道这个“X”是什么类型,所以它会抱怨你传入{{1>} 任何类型。我认为这与编译器抱怨在Class上调用add(...)的原因相同。

当您在Collection<?>方法上为类型明确指定Class<?>时,您并不是说when返回mockDescriptor.getPropertyType(),而是说Class<?> 1}}返回when。然后,编译器检查以确保传入OngoingStubbing<Class<?>>的任何内容与when匹配的类型;由于Class<?>返回前面提到的“getPropertyType()”,它当然与您指定的Class<X>匹配。

所以基本上

Class<?>

在我的IDE中,原始代码的错误消息是

// the inferred type is Class<"some type">
Mockito.when(mockDescriptor.getPropertyType())

// the specified type is Class<"any type">
Mockito.<Class<?>>when(mockDescriptor.getPropertyType())

The method thenReturn(Class<capture#1-of ?>) in the type OngoingStubbing<Class<capture#1-of ?>> is not applicable for the arguments (Class<String>) 是我上面描述的“X”。