Java 调用void方法的CompletableFuture.runAsync()的Mockito测试用例
我需要帮助为下面的方法编写mockito测试用例Java 调用void方法的CompletableFuture.runAsync()的Mockito测试用例,java,spring-boot,junit,java-8,mockito,Java,Spring Boot,Junit,Java 8,Mockito,我需要帮助为下面的方法编写mockito测试用例 public void getCouponAndNotifyAsync(String countryId, String channelId, String storeNumber, String clientId, NotificationRequest notificationRequest) throws FirestoreException, TurneroServiceException { Co
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());
}
@测试
public void getCouponAndNotifyAsync()引发异常{
//doNothing().when(TurnerService).getCouponAndNotify(COUNTRYID、CHANNELID、STORENUMBER、CLIENTID、new NotificationRequest(“ext_rborse@falabella.cl“,”全部“);
CompletableFuture运行异步=CompletableFuture
.runAsync(()->doNothing().when(TurnerService).getCouponAndNotify(COUNTRYID、CHANNELID、STORENUMBER、CLIENTID、new NotificationRequest(“ext_rborse@falabella.cl","全部";;
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());
}
@测试
public void getCouponAndNotifyAsync()引发异常{
//doNothing().when(TurnerService).getCouponAndNotify(COUNTRYID、CHANNELID、STORENUMBER、CLIENTID、new NotificationRequest(“ext_rborse@falabella.cl“,”全部“);
CompletableFuture运行异步=CompletableFuture
.runAsync(()->doNothing().when(TurnerService).getCouponAndNotify(COUNTRYID、CHANNELID、STORENUMBER、CLIENTID、new NotificationRequest(“ext_rborse@falabella.cl","全部";;
assertTrue(ForkJoinPool.commonPool().waitquisition(5,TimeUnit.SECONDS));
assertTrue(runAsync.isDone());
}
我假设您正在其他地方测试getCouponAndNotify()
,所以您不必担心它会引发异常
您将遇到getCouponAndNotifyAsync()
和getCouponAndNotify()
之间的竞争条件。有几种解决方案:
由于您使用的是公共ForkJoinPool
,请执行以下操作:
assertTrue(ForkJoinPool.commonPool().awaitQuiescence(5, TimeUnit.Seconds));
或者,您可以插入一个ExecutorService
,并将其用作supplyAsync()
的第二个参数。您有几个选择:您可以使用一个模拟,您可以使用一个ExecutorService
,或者您可以插入一个标准的Executors.newSingleThreadExecutor()
,然后在测试中调用shutdown()
和waittermination()
您还可以从
getCouponAndNotifyAsync()
返回一个CompletionStage
,您可以在测试中等待它。假设您有以下代码:
public void method() {
CompletableFuture.runAsync(() -> {
//logic
//logic
//logic
//logic
});
}
尝试将其重构为以下内容:
public void refactoredMethod() {
CompletableFuture.runAsync(this::subMethod);
}
private void subMethod() {
//logic
//logic
//logic
//logic
}
之后,通过以下方式测试子方法:
org.powermock.reflect.Whitebox.invokeMethod(classInstance, "subMethod");
Mockito.verify(...)
这不是一个完美的解决方案,但它测试了异步执行中的所有逻辑。在我的测试用例中assertTrue之前编写的任何内容都可以吗?更新了相关的测试用例,但仍然不起作用。是否尝试使用?您最好在测试中扩展类并重写同步方法。您在测试中在哪里调用
getCouponAndNotifyAsync()
?我也不认为模仿像你想象的那样有效。你能解释一下吗?正在控制器类中调用getCouponAndNotifyAsync()。那项测试通过了。