繁体   English   中英

使用 mockito 模拟返回带有通配符的泛型的方法

[英]mocking a method that return generics with wildcard using mockito

我正在使用 mockito 1.9.5。 我有以下代码:

public class ClassA  {

public List<? extends MyInterface> getMyInterfaces() {
    return null;
}

public static void testMock() {
    List<MyInterface> interfaces = new ArrayList<>();
    ClassA classAMock = mock(ClassA.class);
    when(classAMock.getMyInterfaces()).thenReturn(interfaces);      
}

我收到thenReturn(interfaces)的编译错误说:

"The method thenReturn(List<capture#1-of ? extends MyInterface>) in the type 
 OngoingStubbing<List<capture#1-of ? extends MyInterface>> is not applicable for the arguments 
 (List<MyInterface>)"

但是,当我使用 mockito 的thenAnswer方法时,我没有收到错误消息。 谁能告诉我这是怎么回事? 为什么在使用thenReturn方法时会出现错误? ClassA由第三方提供且无法修改时,是否有其他方法可以解决此问题?

编辑:从 Mockito 1.10.x 开始,嵌入在类中的泛型类型现在被 Mockito 用于深存根。 IE。

public interface A<T extends Observer & Comparable<? super T>>  {
  List<? extends B> bList();
  T observer();
}

B b = deep_stubbed.bList().iterator().next(); // returns a mock of B ; mockito remebers that A returns a List of B
Observer o = deep_stubbed.observer(); // mockito can find that T super type is Observer
Comparable<? super T> c = deep_stubbed.observer(); // or that T implements Comparable

Mockito 尽最大努力获取编译器嵌入的类型信息,但是当擦除适用时,mockito 只能返回Object的模拟。


原文:嗯,与 Mockito 相比,泛型更像是一个问题。 对于泛型,你应该阅读Angelika Langer写的关于它们的内容。 对于当前主题,即通配符,请阅读本

但简而言之,您可以使用 Mockito 的其他语法来帮助您解决当前情况:

doReturn(interfaces).when(classAMock).getMyInterfaces();

或者使用 BDD 别名:

willReturn(interfaces).given(classAMock).getMyInterfaces();

不过,您可以编写更通用的包装器。 这将有助于未来的开发人员使用相同的 3rd 方 API。


附带说明:您不应该模拟您不拥有的类型,它会导致许多错误和问题。 相反,您应该有一些包装器。 例如,DAO 和存储库代表了这样的想法,人们将模拟 DAO 或存储库接口,而不是 JDBC/JPA/hibernate 的东西。 有很多关于这个的博客文章:

另一种解决方案(虽然不太可读)是限定when绑定通配符的静态方法调用:

Mockito.<List<? extends MyInterface>>when(classAMock.getMyInterfaces()).thenReturn(interfaces);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM