【问题标题】:A strange generics edge case with Mockito.when() and generic type inference带有 Mockito.when() 和泛型类型推断的奇怪泛型边缘案例
【发布时间】:2012-06-08 16:26:09
【问题描述】:

我正在使用 Mockito 编写一个使用 java.beans.PropertyDescriptor 的测试用例,并且我想模拟 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() 的返回类型?我以前从来没有像那样指定参数。

【问题讨论】:

    标签: java generics mockito


    【解决方案1】:

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

    当您在 when 方法上为类型显式指定 Class&lt;?&gt; 时,并不是说 mockDescriptor.getPropertyType() 返回 Class&lt;?&gt;,而是说 when 返回 OngoingStubbing&lt;Class&lt;?&gt;&gt;。然后,编译器检查以确保您传递给when 的任何内容都是与Class&lt;?&gt; 匹配的类型;因为getPropertyType()返回的是我前面提到的“Class&lt;X&gt;”,它当然匹配你指定的Class&lt;?&gt;

    基本上

    // 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”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多