Mockito.when()和泛型类型推断的一个奇怪的泛型边界案例 [英] A strange generics edge case with Mockito.when() and generic type inference
问题描述
我正在使用Mockito编写一个使用 java.beans.PropertyDescriptor
的测试用例,并且我想模拟 getPropertyType( )
返回一个任意的 Class <?>
对象(在我的例子中, String.class
)。通常情况下,我只需调用:
//我们已经做了一个import static org.mockito.Mockito。*
when(mockDescriptor.getPropertyType())。thenReturn(String.class);
然而,奇怪的是,这不会编译:
无法找到符号方法thenReturn(java.lang.Class< java.lang.String>)
但是,当我指定类型参数而不是依赖于推理时:
Mockito。< ;类<?>>在(mockDescriptor.getPropertyType())thenReturn(String.class)。
一切都是hunky dory。为什么编译器在这种情况下无法正确推断when()的返回类型?
PropertyDescriptor#getPropertyType() code>返回一个
Class <?>
的对象,其中?
表示这是一个类型,但我不知道它是什么。我们称这种类型为X。因此当(mockDescriptor.getPropertyType())
创建一个 OngoingStubbing
,其方法 thenReturn(Class
Class
>。 Class
类。我认为这是编译器抱怨在 Collection <?>>
add(...)
当您为类型明确指定
Class <?>< / code>当
方法,你不是说 mockDescriptor.getPropertyType()
返回一个 Class <?>< / code>,当返回一个
是一个匹配 OngoingStubbing
时,你说 Class <?>> $ c $的类型时,编译器会检查以确定传入
C>;因为
getPropertyType()
返回 Class< X>
我前面提到过,它当然匹配 Class <?>
你指定的。
所以基本上
//推断的类型是Class<某种类型>
Mockito.when(mockDescriptor.getPropertyType())
//指定的类型是Class<any type>
Mockito。< Class<>> when(mockDescriptor.getPropertyType())
在我的IDE中,原始代码的错误消息是
方法thenReturn(Class
I'm writing a test case that uses a java.beans.PropertyDescriptor
using Mockito, and I want to mock the behavior of getPropertyType()
to return an arbitrary Class<?>
object (in my case, String.class
). Normally, I would do that by just invoking:
// we already did an "import static org.mockito.Mockito.*"
when(mockDescriptor.getPropertyType()).thenReturn(String.class);
However, oddly, this does not compile:
cannot find symbol method thenReturn(java.lang.Class<java.lang.String>)
But when I specify the type parameter instead of depending on inference:
Mockito.<Class<?>>when(mockDescriptor.getPropertyType()).thenReturn(String.class);
everything is hunky dory. Why can't the compiler correctly infer the return type of when() in this case? I have never had to specify the parameter before like that.
PropertyDescriptor#getPropertyType()
returns an object of Class<?>
, where the ?
means "this is a type, but I don't know what it is". Let's call this type "X". So when(mockDescriptor.getPropertyType())
creates an OngoingStubbing<Class<X>>
, whose method thenReturn(Class<X>)
can only accept objects of Class<X>
. But the compiler doesn't know what type this "X" is, so it will complain about you passing in a Class
of any type. I think this is the same reason the compiler complains about calling add(...)
on a Collection<?>
.
When you explicitly specify Class<?>
for the type on the when
method, you're not saying that mockDescriptor.getPropertyType()
returns a Class<?>
, you're saying that when
returns an OngoingStubbing<Class<?>>
. Then, the compiler checks to make sure whatever you're passing into when
is of a type that matches Class<?>
; since getPropertyType()
returns the "Class<X>
" I mentioned earlier, it of course matches the Class<?>
you specified.
So basically
// the inferred type is Class<"some type">
Mockito.when(mockDescriptor.getPropertyType())
// the specified type is Class<"any type">
Mockito.<Class<?>>when(mockDescriptor.getPropertyType())
In my IDE, the error message for your original code is
The method thenReturn(Class<capture#1-of ?>) in the type OngoingStubbing<Class<capture#1-of ?>> is not applicable for the arguments (Class<String>)
That capture#1-of ?
is the "X" I described above.
这篇关于Mockito.when()和泛型类型推断的一个奇怪的泛型边界案例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!