9

我正在编写一个使用java.beans.PropertyDescriptorusing Mockito 的测试用例,并且我想模拟getPropertyType()返回任意Class<?>对象(在我的情况下为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>)

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

Mockito.<Class<?>>when(mockDescriptor.getPropertyType()).thenReturn(String.class);

一切都很好。在这种情况下,为什么编译器不能正确推断 when() 的返回类型?我以前从来没有像那样指定参数。

4

1 回答 1

13

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

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

所以基本上

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

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

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

The method thenReturn(Class<capture#1-of ?>) in the type OngoingStubbing<Class<capture#1-of ?>> is not applicable for the arguments (Class<String>)

capture#1-of ?就是我上面描述的“X”。

于 2012-06-08T17:00:38.913 回答