Unit testing 需要使用CompletableFuture为源代码编写Junit测试(模拟)的帮助吗
目标是为具有完全基于未来的异步操作的代码编写带有模拟的单元测试用例。Unit testing 需要使用CompletableFuture为源代码编写Junit测试(模拟)的帮助吗,unit-testing,java-8,mockito,completable-future,Unit Testing,Java 8,Mockito,Completable Future,目标是为具有完全基于未来的异步操作的代码编写带有模拟的单元测试用例。 参考各种示例(包括stackoverflow),未找到任何信息。书中的大多数示例、各种在线源代码以及堆栈溢出都指向测试代码中CompleteableFuture的使用 在这里,我希望模拟单元测试的源代码有一个完整的未来 如果有,请提供任何指示 针对单元测试的源代码:- 公共字符串getSomeResultThruAsync(整数a){ 完整的未来结果; resultFuture=CompletableFuture.Supply
参考各种示例(包括stackoverflow),未找到任何信息。书中的大多数示例、各种在线源代码以及堆栈溢出都指向测试代码中CompleteableFuture的使用 在这里,我希望模拟单元测试的源代码有一个完整的未来 如果有,请提供任何指示 针对单元测试的源代码:-
公共字符串getSomeResultThruAsync(整数a){
完整的未来结果;
resultFuture=CompletableFuture.SupplySync(()->{
试一试{
返回someFactory.getSomeResultMethod(a);
}
捕获(例外e){
抛出新的CustomException(“自定义代码和消息”);
}
},executorService);//单独初始化的自定义executorService;在公共池之外使用
返回resultFuture.complete();
}
}
带有Mock(mockito)的单元测试代码:-
@测试
public void testGetSomeResultThruAsync()
{
//someFactory是Factory类的模拟对象
Mockito.when(someFactory.getSomeResultMethod(any(String.class))
。然后返回(“测试结果”);
……一些基类代码初始化,然后调用getSomeResultThruAsync方法
}
在通常情况下,上述代码在模拟时工作良好。
这里是完整的未来控制,永远不会返回。我尝试了一些朋友或同事建议的其他方法。结果与上面的基本相同。假设您想在下面的课程中进行单元测试:
private static class SomeClass {
private final SomeFactory someFactory;
private final Executor executorService;
public SomeClass(SomeFactory someFactory, Executor executorService) {
this.someFactory = someFactory;
this.executorService = executorService;
}
public CompletableFuture<String> getSomeResultAsync(Integer a) {
return CompletableFuture.supplyAsync(() -> {
try {
return someFactory.getSomeResultMethod(a);
} catch (Exception e) {
throw new CustomException("custom code and message");
}
}, executorService);
}
}
私有静态类SomeClass{
私人最终工厂;
私人最终执行人服务;
公共SomeClass(SomeFactory SomeFactory,Executor Executor Service){
this.someFactory=someFactory;
this.executorService=executorService;
}
公共CompletableFuture getSomeResultAsync(整数a){
返回CompletableFuture.SupplySync(()->{
试一试{
返回someFactory.getSomeResultMethod(a);
}捕获(例外e){
抛出新的CustomException(“自定义代码和消息”);
}
}(执行人服务);
}
}
这就是你可以做到的:
public class SomeClassTest {
private Executor executor = Runnable::run; // same-thread executor
private SomeFactory someFactory = Mockito.mock(SomeFactory.class);
private SomeClass someClass = new SomeClass(someFactory, executor);
@Test
public void someResultIsReturnedIfAsyncCallCompletesWithoutErrors() throws Exception {
Mockito.when(someFactory.getSomeResultMethod(1)).thenReturn("test");
CompletableFuture<String> resultAsync = someClass.getSomeResultAsync(1);
String result = resultAsync.get();
Assertions.assertThat(result).isEqualTo("test");
}
@Test
public void customExceptionIsThrownIfAsyncCallFailesWithError() throws Exception {
Mockito.when(someFactory.getSomeResultMethod(1)).thenThrow(new RuntimeException());
Assertions.assertThatThrownBy(() -> someClass.getSomeResultAsync(1).get())
.isInstanceOf(ExecutionException.class)
.hasCause(new CustomException("custom code and message"));
}
}
公共类SomeClassTest{
私有执行器Executor=Runnable::run;//同一线程执行器
私有SomeFactory SomeFactory=Mockito.mock(SomeFactory.class);
私有SomeClass SomeClass=新的SomeClass(someFactory,executor);
@试验
public void someResultisReturneDiFasyncCallCompleteWithOutErrors()引发异常{
Mockito.when(someFactory.getSomeResultMethod(1)),然后返回(“测试”);
CompletableFuture resultAsync=someClass.getSomeResultAsync(1);
字符串结果=resultAsync.get();
断言.断言(结果).isEqualTo(“测试”);
}
@试验
public void customExceptionIshirRownIfasyncCallFailesWitherRor()引发异常{
Mockito.when(someFactory.getSomeResultMethod(1)).thenthow(newruntimeexception());
Assertions.assertThatThrownBy(()->someClass.getSomeResultAsync(1.get())
.isInstanceOf(ExecutionException.class)
.hasCause(新的自定义例外(“自定义代码和消息”);
}
}
注:
org.assertj.core.api.Assertions
someFactory.getSomeResultMethod(a)
封装在CompletableFuture
中,然后调用complete
(我想,您实际上的意思是get
).这就是为什么我使用另一个示例来演示单元测试的方法CompletableFuture
getSomeResultThruAsync
方法首先有什么意义?为什么在阻止调用线程时启动异步操作?顺便说一下,您的return null;
语句不仅是糟糕的编码风格,而且是无效的,因为无法访问代码位置。此外,还有不一致性根据getSomeResultMethod
的参数类型;一旦你传递了字符串,然后是整数
…问题中的代码不完整,因此不允许重现问题。你能提供一个参数吗?另外,你试过调试你的测试吗?@Holger:删除了原始问题中的空返回。在实际的方法中,输入是一个字典,它有一些特定于内部团队的细节。输出是一个基于getSomeResultMethod结果的处理信息。这并不能解释为什么在等待结果时使用CompletableFuture
。您可以直接调用getSomeResultMethod
。@Holger:用最新的更改更新了代码。删除get并替换为complete。在实际代码中,我们看到3秒的改进。现在的问题是对源代码进行单元测试。现在是否有进一步的指针?