嘲笑一种方法,使用mockito返回带有通配符的generics

我正在使用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开始,embedded类中的genericstypes现在被Mockito用于深存根。 即。

 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尽力获取编译器embedded的types信息,但是当删除应用时,mockito不能做任何事情,只能返回Object的模拟。


原文 :那么仿制药的问题比Mockito更重要。 对于generics,你应该阅读什么安格里卡兰格写在他们身上。 对于当前的话题,即通配符,请阅读本节 。

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

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

或者用BDD别名:

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

不过,你可以编写更普遍友好的包装。 这将有助于未来的开发者使用相同的第三方API。


作为一个方面说明:你不应该嘲笑你不拥有自己的types,这可能会导致很多错误和问题。 相反,你应该有一些包装。 例如,DAO和存储库代表了这样的想法,人们将模拟DAO或存储库接口,而不是JDBC / JPA / Hibernate的东西。 有很多关于这方面的博客文章:

另一个解决scheme(尽pipe可读性较差)是限定when绑定通配符的静态方法调用:

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