Mockito.when()和泛型类型推断的一个奇怪的泛型边界案例 [英] A strange generics edge case with Mockito.when() and generic type inference

查看:1798
本文介绍了Mockito.when()和泛型类型推断的一个奇怪的泛型边界案例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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 的对象。但是编译器不知道这个X是什么类型,所以它会抱怨你传入任何类型的 Class 类。我认为这是编译器抱怨在 Collection <?>> add(...) >。



当您为类型明确指定 Class <?>< / code>当方法,你不是说 mockDescriptor.getPropertyType()返回一个 Class <?>< / code>,当返回一个 OngoingStubbing > 时,你说。然后,当是一个匹配 Class <?>> C>;因为 getPropertyType()返回 Class< X> 我前面提到过,它当然匹配 Class <?> 你指定的。



所以基本上

  //推断的类型是Class<某种类型> 
Mockito.when(mockDescriptor.getPropertyType())

//指定的类型是Class<any type>
Mockito。< Class<>> when(mockDescriptor.getPropertyType())

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

 方法thenReturn(Class   

capture# 1?是我上面描述的X。


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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆