我正在尝试模拟ExecutorService,但它一直在给出编译错误。我正在尝试的代码如下:
ExecutorService executorService = mock(ExecutorService.class);
Future<A> mockedFuture = mock(Future.class);
List<Future<A>> list = Lists.newArrayList(mockedFuture);
when(executorService.invokeAll(any())).thenReturn(list);
当我编译它时,它返回以下错误:
error: no suitable method found for thenReturn(List<Future<A>>)
[javac] when(executorService.invokeAll(any())).thenReturn(futureList);
[javac] ^
[javac] method OngoingStubbing.thenReturn(List<Future<Object>>) is not applicable
[javac] (argument mismatch; List<Future<A>> cannot be converted to List<Future<Object>>)
[javac] method OngoingStubbing.thenReturn(List<Future<Object>>,List<Future<Object>>...) is not applicable
[javac] (argument mismatch; List<Future<A>> cannot be converted to List<Future<Object>>)
有什么主意吗?
答案 0 :(得分:2)
此处Mockito.any()
返回由调用目标推断的类型,即executorService.invokeAll()
。但是executorService.invokeAll()
也没有声明更具体的类型,因为它也依赖于目标推断:Mockito.when(...)
。
any()
返回的类型取决于invokeAll()
返回的类型,而when()
返回的类型也取决于。
但是invokeAll()
和when()
都没有在通用集合中指定A
类型。
因此T
方法的通用invokeAll()
类型定义为:
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
将被编译器视为Object
,例如:
<Object> List<Future<Object>> invokeAll(Collection<? extends Callable<Object>> tasks)
因此any()
将返回Collection<? extends Callable<Object>>
类型。
在这些情况下,无法返回thenReturn()
但声明的List<Future<Object>>
类型的List<Future<A>>
无法编译:
argument mismatch; List<Future<A>> cannot be converted to List<Future<Object>>)
要解决您的问题,您需要对Mockito.any()
进行未经检查的强制转换(但您知道它会起作用):
Mockito.when(executorService.invokeAll((Collection<Callable<A>>)Mockito.any())).thenReturn(list);
或者,通过在变量中显式设置Mockito.any()
的返回值来解决目标推断:
Collection<Callable<A>> any = Mockito.any();
Mockito.when(executorService.invokeAll(any)).thenReturn(list);
答案 1 :(得分:1)
您应该在以下方面获得更大的成功
ExecutorService executorService = mock(ExecutorService.class);
Future<Object> mockedFuture = mock(Future.class);
List<Future<Object>> list = Lists.newArrayList(mockedFuture);
when(executorService.invokeAll(any())).thenReturn(list);
错误消息有一个提示:
argument mismatch; List<Future<A>> cannot be converted to List<Future<Object>>
这是因为对于Java泛型,List<Future<A>
不是List<Future<Object>>
(Future<A>
也不是Future<Object>
)。
为什么会出现这种情况,有很多很好的解释,请看一下Java的SO的SO。