Java 是否可以在Mockito中验证在不同线程中运行的模拟方法?
我有一个方法如下Java 是否可以在Mockito中验证在不同线程中运行的模拟方法?,java,mocking,mockito,powermock,Java,Mocking,Mockito,Powermock,我有一个方法如下 public void generateCSVFile(final Date billingDate) { asyncTaskExecutor.execute(new Runnable() { public void run() { try { accessService.generateCSVFile(billingDate); } catch (Exception e)
public void generateCSVFile(final Date billingDate) {
asyncTaskExecutor.execute(new Runnable() {
public void run() {
try {
accessService.generateCSVFile(billingDate);
} catch (Exception e) {
LOG.error(e.getMessage());
}
}
});
}
我嘲笑:
PowerMockito.doNothing().when(accessService).generateCSVFile(billingDate);
但当我核实时:
verify(rbmPublicViewAccessService, timeout(100).times(1)).generateCSVFile(billingDate);
它给了我一个未被调用的消息。这是因为它是通过单独的线程调用的,并且可以验证在不同线程中调用的方法吗?在验证调用时,
asyncTaskExecutor
很可能尚未执行Runnable
,从而导致单元测试中出现验证错误
解决此问题的最佳方法是在生成的线程上加入,并在验证调用之前等待执行
如果无法获取线程实例,一种可能的解决方法是模拟asyncTaskExecutor
并实现它,以便它直接执行runnable
private ExecutorService executor;
@Before
public void setup() {
executor = mock(ExecutorService.class);
implementAsDirectExecutor(executor);
}
protected void implementAsDirectExecutor(ExecutorService executor) {
doAnswer(new Answer<Object>() {
public Object answer(InvocationOnMock invocation) throws Exception {
((Runnable) invocation.getArguments()[0]).run();
return null;
}
}).when(executor).submit(any(Runnable.class));
}
私有执行器服务执行器;
@以前
公共作废设置(){
executor=mock(ExecutorService.class);
执行者直接执行者(执行者);
}
受保护的无效实现DirectExecutor(ExecutorService executor){
doAnswer(新答案){
公共对象应答(InvocationMock调用)引发异常{
((Runnable)invocation.getArguments()[0]).run();
返回null;
}
}).何时(执行者)。提交(任何(可运行的类));
}
我也遇到了同样的问题,并使用了timeout参数
但参数为0时,如中所示
verify(someClass, timeout(0)).someMethod(any(someParameter.class));
它是有效的。我假设测试线程会让步,因此另一个线程有机会完成它的工作,适当地调用mock。
不过它闻起来还是有点像黑客。进一步重复Tom的答案-使用Java 8 Lambdas,您现在可以使用以下代码来模拟执行器,这稍微简单一些:
doAnswer((Answer<Void>)invocation -> {
((Runnable)invocation.getArgument(0)).run();
return null;
}).when(executorService).submit(any(Runnable.class));
doAnswer((应答)调用->{
((Runnable)invocation.getArgument(0)).run();
返回null;
}).when(executorService).提交(任意(Runnable.class));
也许这些信息有帮助:?:(链接未打开。404Mockito已被google代码存档。请检查一下,真见鬼,谢谢!超时(0)对我也不起作用。超时(2000)和许多其他数字一样工作得很好。而不是(答案)调用
您可以直接使用i
。几天后发现。效果非常好。非常感谢!