CompletableFuture.runAsync() 的 Mockito 测试用例调用 void 方法

Rah*_*hul 4 java junit mockito java-8 spring-boot

我需要帮助为下面的方法编写模拟测试用例。

public void getCouponAndNotifyAsync(String countryId, String channelId,
        String storeNumber, String clientId, NotificationRequest notificationRequest)
        throws FirestoreException, TurneroServiceException {
    CompletableFuture.runAsync(() -> getCouponAndNotify(countryId, channelId,
            storeNumber, clientId, notificationRequest));
}
Run Code Online (Sandbox Code Playgroud)

其中 getCouponAndNotify() 是一个 void 方法。

尝试了下面但它不起作用

@Test
    public void getCouponAndNotifyAsync() throws Exception {
        //doNothing().when(turneroService).getCouponAndNotify(COUNTRYID, CHANNELID, STORENUMBER, CLIENTID, new NotificationRequest("ext_rborse@falabella.cl", "all"));

        CompletableFuture<Void> runAsync = CompletableFuture
                .runAsync(() -> doNothing().when(turneroService).getCouponAndNotify(COUNTRYID, CHANNELID, STORENUMBER, CLIENTID, new NotificationRequest("ext_rborse@falabella.cl", "all")));

        assertTrue(runAsync.isDone());

    }
Run Code Online (Sandbox Code Playgroud)

更新了测试用例但仍然不起作用。

@Test
    public void getCouponAndNotifyAsync() throws Exception {
        //doNothing().when(turneroService).getCouponAndNotify(COUNTRYID, CHANNELID, STORENUMBER, CLIENTID, new NotificationRequest("ext_rborse@falabella.cl", "all"));

        CompletableFuture<Void> runAsync = CompletableFuture
                .runAsync(() -> doNothing().when(turneroService).getCouponAndNotify(COUNTRYID, CHANNELID, STORENUMBER, CLIENTID, new NotificationRequest("ext_rborse@falabella.cl", "all")));

        assertTrue(ForkJoinPool.commonPool().awaitQuiescence(5, TimeUnit.SECONDS));
        assertTrue(runAsync.isDone());

    }
Run Code Online (Sandbox Code Playgroud)

Dav*_*ann 6

我假设您正在getCouponAndNotify()其他地方进行测试,因此您不必担心它会引发异常。

getCouponAndNotifyAsync()你将遇到的是和返回之间的竞争条件getCouponAndNotify()。对此有几种解决方案:

既然您使用的是 common ForkJoinPool,请执行以下操作

assertTrue(ForkJoinPool.commonPool().awaitQuiescence(5, TimeUnit.Seconds));
Run Code Online (Sandbox Code Playgroud)

它等待任务完成

或者,您可以注入 anExecutorService并将其用作 的第二个参数supplyAsync()。你有几个选择:你可以使用模拟,你可以使用ExecutorService当前线程一起运行的,或者你可以注入一个标准Executors.newSingleThreadExecutor(),然后在你的测试中调用shutdown()and awaitTermination()

您还可以返回一个可以在测试中等待的CompletionStage<Void>对象。getCouponAndNotifyAsync()