首页 > 解决方案 > 调用 void 方法的 CompletableFuture.runAsync() 的 Mockito 测试用例

问题描述

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

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

其中 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());

    }

更新了测试用例,但仍然无法正常工作。

@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());

    }

标签: javaspring-bootjunitjava-8mockito

解决方案


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

您将遇到的是getCouponAndNotifyAsync()getCouponAndNotify()返回之间的竞争条件。有几个解决方案:

由于您使用的是 common ForkJoinPool,请执行

assertTrue(ForkJoinPool.commonPool().awaitQuiescence(5, TimeUnit.Seconds));

它等待任务完成

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

你也可以返回一个你可以CompletionStage<Void>getCouponAndNotifyAsync()测试中等待的。


推荐阅读