我正在编写一个使用 java.beans.PropertyDescriptor
的测试用例使用 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() 的返回类型?我以前从来没有像那样指定过参数。
最佳答案
PropertyDescriptor#getPropertyType()
返回 Class<?>
的对象, 其中?
意思是“这是一种类型,但我不知道它是什么”。我们称这种类型为“X”。所以when(mockDescriptor.getPropertyType())
创建一个 OngoingStubbing<Class<X>>
,其方法 thenReturn(Class<X>)
只能接受 Class<X>
的对象.但是编译器不知道这个“X”是什么类型,所以它会提示你传入了一个Class
。 任何类型。我认为这与编译器提示调用 add(...)
的原因相同。在 Collection<?>
上.
当您明确指定 Class<?>
时对于 when
上的类型方法,你不是说 mockDescriptor.getPropertyType()
返回 Class<?>
,你是说 when
返回 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”。
关于java - 使用 Mockito.when() 和泛型类型推断的奇怪泛型边缘案例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10952629/