在测试中模拟 CompletionException
Posted
技术标签:
【中文标题】在测试中模拟 CompletionException【英文标题】:Simulate CompletionException in a test 【发布时间】:2018-01-21 06:12:29 【问题描述】:我有一个类 HttpClient
,它有一个返回 CompletableFuture
的函数:
public class HttpClient
public static CompletableFuture<int> getSize()
CompletableFuture<int> future = ClientHelper.getResults()
.thenApply((searchResults) ->
return searchResults.size();
);
return future;
然后另一个函数调用这个函数:
public class Caller
public static void caller() throws Exception
// some other code than can throw an exception
HttpClient.getSize()
.thenApply((count) ->
System.out.println(count);
return count;
)
.exceptionally(ex ->
System.out.println("Whoops! Something happened....");
);
现在,我想写一个测试来模拟ClientHelper.getResults
失败,所以我写了这个:
@Test
public void myTest()
HttpClient mockClient = mock(HttpClient.class);
try
Mockito.doThrow(new CompletionException(new Exception("HTTP call failed")))
.when(mockClient)
.getSize();
Caller.caller();
catch (Exception e)
Assert.fail("Caller should not have thrown an exception!");
此测试失败。 exceptionally
中的代码永远不会被执行。但是,如果我正常运行源代码并且 HTTP 调用确实失败了,它会转到 exceptionally
块就好了。
我必须如何编写测试才能执行exceptionally
代码?
【问题讨论】:
【参考方案1】:我在测试中这样做了:
CompletableFuture<Long> future = new CompletableFuture<>();
future.completeExceptionally(new Exception("HTTP call failed!"));
Mockito.when(mockClient.getSize())
.thenReturn(future);
不确定这是否是最好的方法。
【讨论】:
我认为这是最好的方法:CompletableFuture 是一个广泛使用且经过良好测试的库,因此您可以依赖它来测试您的代码,而不是尝试使用 Mockito 复制其行为。 (当然,Mockito 是在您模拟的被测系统的依赖项中提供 Future 的一种不错的方式。)以上是关于在测试中模拟 CompletionException的主要内容,如果未能解决你的问题,请参考以下文章
如何使用@WebMvcTest 春季测试在模拟服务中注入模拟的restTemplate