我实现了一个模拟的ExecutorService来立即返回结果,而无需创建线程:
public static ExecutorService createMock() throws Exception {
ExecutorService executorServiceMock = EasyMock.createMock(ExecutorService.class);
Future future = EasyMock.createMock(Future.class);
Capture<Callable<?>> callableCapture = new Capture<>();
EasyMock.expect(executorServiceMock.submit(EasyMock.<Callable<?>>capture(callableCapture))).andReturn(future).anyTimes();
EasyMock.expect(future.get()).andAnswer(() -> callableCapture.getValue().call()).anyTimes();
executorServiceMock.shutdown();
EasyMock.expectLastCall().anyTimes();
EasyMock.replay(future, executorServiceMock);
return executorServiceMock;
}
问题是它总是返回相同的 [模拟] Future 对象。我需要根据传递给 executorServiceMock.submit() 的可调用对象返回 Future mock 的新实例我尝试使用PowerMock.expectNew(Future.class),但它抱怨"在类'java.util.concurrent.Future'中找不到参数类型为[ ]的构造函数"
首先是"不要嘲笑你不拥有的类型!通过链接,您可能会找到几个不应该这样做的原因。
但是,如果你真的想这样做,那么通过答案女巫替换返回模拟每次都会创建一个新的nock:
EasyMock.expect(executorServiceMock.submit(EasyMock.<Callable<?>>capture(callableCapture))).andAnswer(() -> {
Future future = EasyMock.createMock(Future.class);
EasyMock.expect(future.get()).andAnswer(() -> callableCapture.getValue().call()).anyTimes();
EasyMock.replay(future);
return future;
}).anyTimes();
顺便说一下,您不能期望PowerMock.expectNew(Future.class)
Future
因为这是接口,无法创建。
捕获将始终返回最后一个捕获的对象。在您的情况下,您似乎想要同步提交和获取。
所以,我认为你应该做到以下几点:
ExecutorService executorServiceMock = createMock(ExecutorService.class);
expect(executorServiceMock.submit(EasyMock.<Callable<?>>anyObject()))
.andAnswer(() -> {
Future future = createMock(Future.class);
Object value = ((Callable<?>) getCurrentArguments()[0]).call();
expect(future.get()).andReturn(value);
replay(future);
return future;
})
.anyTimes();
executorServiceMock.shutdown();
expectLastCall().anyTimes();
replay(executorServiceMock);
return executorServiceMock;
下面的代码解决了我的问题。
@Mock
private ThreadPoolExecutor executorPool;
Future<String> result = CompletableFuture.completedFuture("S3PATH");
when(executorPool.submit(Mockito.<Callable<String>> anyObject())).thenReturn(result);