【问题标题】:mock a method with generic return type with mockito使用 mockito 模拟具有通用返回类型的方法
【发布时间】:2011-12-23 12:18:07
【问题描述】:


这是我的问题:

public interface Containter extends ModelElement{
     List<? extends ModelElement> getChildren();
}

有几个类实现了容器,我想模拟它们:

public class MockMama {
   public static <T extends Containter, Y extends ModelElement> T bornContainer(Class<T> clazz, Y ... children) {
           T container = mock(clazz);
           when(container.getChildren()).thenReturn(Arrays.asList(children));
           return container;
   }
}

但这不起作用。 Eclipse 说“OngoingStubbing> 类型中的 thenReturn(List) 方法不适用于参数 (List)”。我还尝试将 List&lt;? extends ModelElement&gt; 类型的本地声明变量传递给 thenReturn 但这也无济于事。
非常感谢和欢迎任何帮助:)

【问题讨论】:

  • 好的,看起来可以通过引入额外的本地变量来修复它,比如 List list = Arrays.asList(children); when(container.getChildren()).thenReturn(list);有什么方法可以做到不引起原始类型警告?

标签: java generics mockito


【解决方案1】:

您的问题是无法保证 getChildren() 返回的类型与您的 BornContainer 方法的 varargs 参数的类型相匹配。所以编译器抱怨这个是正确的。使用中间局部变量确实会将编译器错误变成潜在的运行时问题。

在我看来,您的“容器”实际上应该是一个泛型类,因为它的行为取决于 getChildren() 返回的列表中的类型。看看我对你的例子的重写。这没有编译错误或警告。

public interface Containter<Z extends ModelElement> extends ModelElement{      
    List<Z> getChildren(); 
}

public class MockMama {    
    public static <Y extends ModelElement, T extends Containter<Y>> T bornContainer( Class<T> clazz, Y ... children) {            
        T container = mock(clazz);            
        when(container.getChildren()).thenReturn( Arrays.asList(children));            
        return container;    
    } 
}

希望这会有所帮助。

【讨论】:

  • 感谢您的回答。但是 Container 真的不能是通用的——它应该能够返回任何类型的 ModelElements。另外我很抱歉,问题中有一个错字 - 不应该有 Z2ModelElements,所有的元素都只是 ModelElements。那么容器的getChildren和method generic都是Y扩展ModelElement,为什么还要有额外的保证呢?
  • 因为getChildren返回的Y不一定匹配传入bornContainerYs;并且编译器正试图保护您免受自己的伤害。但是,如果这些方法应该能够处理任何类型的ModelElement,那么也许你可以完全放弃Y——也就是说,getChildren 的返回类型可以是List&lt;ModelElement&gt;,第二个参数是@ 987654330@ 可能只是 ModelElement...
  • 好的。我想我明白了。谢谢。
【解决方案2】:

通常在测试中,您可以忽略未经检查或原始类型的警告。因此,使用诸如 @SupressWarning("unchecked") 之类的编译器指令来注释您的测试通常是安全的。

【讨论】:

  • 嗯,是的,它可以被抑制,但我不明白为什么原始代码无法编译。这让我很紧张 :) 我觉得这是某种废话“你可以做 x,除非是 y,除非 y 做 z,在这种情况下你可以……”Ken Arnold 谈到 weblogs.java.net/blog/arnold/archive/2005/06/…跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-11-27
  • 2020-01-21
  • 1970-01-01
  • 1970-01-01
  • 2015-12-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多