Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 是否可以在Mockito中验证在不同线程中运行的模拟方法?_Java_Mocking_Mockito_Powermock - Fatal编程技术网

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
。几天后发现。效果非常好。非常感谢!