ManagedExecutorService
(在 Wildfly 9 中)
public class FooService{
@Resource
ManagedExecutorService executorService;
}
ExecutorService
@RunWith(MockitoJUnitRunner.class)
public class FooServiceTest{
@Spy
ManagedExecutorService executorService = Executors.newFixedThreadPool(5);
}
这段代码显然无法编译,因为
ExecutorService
不是 ManagedExecutorService
。
在服务中使用
ExecutorService
时,测试运行没有错误,但是Wildfly无法注入服务。
public class FooService{
@Resource
ExecutorService executorService;
}
@RunWith(MockitoJUnitRunner.class)
public class FooServiceTest {
@Spy
ExecutorService executorService = Executors.newFixedThreadPool(5);
}
可以通过委托给
ManagedExecutorService
来创建 ExecutorService
:
@Spy
ManagedExecutorService executorService = new ManagedExecutorService() {
ExecutorService executorService = Executors.newFixedThreadPool(5);
@Override
public void shutdown() {
executorService.shutdown();
}
// delegate for all (12) methods
}
是否有更简单的方法可以在测试中使用
ExecutorService
而不更改Wildfly中运行的服务?
我使用注入模式:
class DefaultImpl {
static DefaultFactory me;
static DefaultFactory getCurrentInstance()
{ if (me == null) {
me = new DefaultFactory();
}
return me;
}
void setCurrentInstance(DefaultFactory df){
me = df;
}
ExecutorService getExecutorService(){
// lookup and return ManagedExecutorService
}
}
class TestImpl extends DefaultImpl{
TestImpl(){
DefaultFactory.setCurrentInstance(this); <-- this now sets your TestImpl for any call
}
ExecutorService getExecutorService(){
ExecutorService executorService = Executors.newFixedThreadPool(5);
return executorService;
}
}
//junit
@Test
void someTest(){
new TestImpl();
// do something all your calls will use non managed executor service
}
您还可以从 junit setup() 调用 new TestImpl()。另外,如果您想让它更灵活,那么您可以拥有一个 BaseImpl 并让 DefaultImpl 和 TestImpl 扩展它。
希望这有帮助!
如果有人仍在寻找答案:我嘲笑了
ManagedExecutorService
并使用 CompletableFuture.runAsync(...)
与 ExecutorService
组合来实现嘲笑的行为:
@ExtendWith(MockitoExtension.class)
class SomeServiceTest {
@Mock
private ManagedExecutorService managedExecutorService;
@Mock
private ServiceCalledAsyncly serviceCalledAsyncly;
private SomeService someService;
@BeforeEach
void setUp() {
var testExecutorService = Executors.newFixedThreadPool(10);
when(managedExecutorService.runAsync(any())).then(invocation -> {
Runnable runnable = invocation.getArgument(0);
return CompletableFuture.runAsync(runnable, testExecutorService);
});
doAnswer((invocation) -> {
Thread.sleep(1000);
return null;
}).when(serviceCalledAsyncly).doSomethingLongRunning();
someService = new SomeService(managedExecutorService, serviceCalledAsyncly);
}
// your tests...
}