简体   繁体   English

如何对包含 CompletableFuture 的方法进行单元测试?

[英]How do I unit test a method that contains a CompletableFuture?

I tried looking this up, but couldn't quite understand the examples I found.我试着查了一下,但不太明白我找到的例子。 I have a class with a Spring AfterPropertiesSet() method that calls 2 other methods to spin off asynch calls.我有一个带有 Spring AfterPropertiesSet()方法的类,它调用 2 个其他方法来分离异步调用。 I'm at a loss how as to to unit test them.我不知道如何对它们进行单元测试。 The method startProcessingThread() looks like this:方法startProcessingThread()看起来像这样:

void startProcessingThread(executor) {
    CompletableFuture.runAsync(() -> {
        Path filePath = null;       
        do {
            filePath = retrieveFromFileQueue();
            submitFileForProcessing(filePath);            
        } while (keepRunning);
    }, executor)
    .handle((theVoid, exception) -> {           
        if (exception != null) {
            LOG.error("Error submitting file for processing: " + exception);            
        }
        return null;
    });
}

I don't want to rewrite the CompletableFuture in the test method (do I?).我不想在测试方法中重写CompletableFuture (是吗?)。 So I figured I need to call startProcessingThread() , using Mocks (from Mockito) inside the methods that need them ( retrieveFromFileQueue() and submitFileForProcessing() ).所以我想我需要调用startProcessingThread() ,在需要它们的方法中使用 Mocks(来自 Mockito)( retrieveFromFileQueue()submitFileForProcessing() )。 But what about the CompletableFuture itself?但是CompletableFuture本身呢? Should I mock that?我应该嘲笑吗? I'm sorry, but I'm really confused...对不起,但我真的很困惑......

You should avoid non deterministic logic in your test and so I would advise to avoid sleep.您应该在测试中避免使用非确定性逻辑,因此我建议避免睡眠。 Instead you can use Mockito's "when" instead of "verify" and wait until the action was performed:相反,您可以使用 Mockito 的“when”而不是“verify”并等待操作执行:

final xyz[] result = new[]{null};
final CountDownLatch latch = new CountDownLatch(1);
when(submitFileForProcessing(...).thenAnswer((Answer<Lwm2mCommand>) invocationOnMock ->
{
    result[0] = invocationOnMock.getArgument(index); // if you need to check the values passed to your method call

    latch.countDown();
}

// Call your method
        assertTrue(latch.await(60L, TimeUnit.SECONDS));
// If needed check the parameters passed to the mocked method

One more tip: I wouldn't mock the actual class under test - instead I would mock one of the dependencies used.另一个提示:我不会模拟被测试的实际类 - 相反,我会模拟使用的依赖项之一。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM