Nir*_*ane 1 java-8 completable-future
如何避免单元测试中的手动睡眠。假设在下面的代码中,Process和notify需要大约 5 秒的时间进行处理。所以为了完成处理,我添加了 5 秒的睡眠。
public class ClassToTest {
public ProcessService processService;
public NotificationService notificationService;
public ClassToTest(ProcessService pService ,NotificationService nService ) {
this.notificationService=nService;
this.processService = pService;
}
public CompletableFuture<Void> testMethod()
{
return CompletableFuture.supplyAsync(processService::process)
.thenAccept(notificationService::notify);
}
}
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法来处理这个问题?
@Test
public void comletableFutureThenAccept() {
CompletableFuture<Void> thenAccept =
sleep(6);
assertTrue(thenAccept.isDone());
verify(mocknotificationService, times(1)).notify(Mockito.anystring());
}
Run Code Online (Sandbox Code Playgroud)
通常,您要测试底层操作是否以预期结果完成,是否具有预期副作用,或者至少在不引发异常的情况下完成。这可以很容易地实现
@Test
public void comletableFutureThenAccept() {
CompletableFuture<Void> future = someMethod();
future.join();
/* check for class under test to have the desired state */
}
Run Code Online (Sandbox Code Playgroud)
join()将等待完成并返回结果(在 的情况下您可以忽略Void),如果未来异常完成则抛出异常。
如果在特定时间内完成实际上是测试的一部分,只需使用
@Test(timeout = 5000)
public void comletableFutureThenAccept() {
CompletableFuture<Void> future = someMethod();
future.join();
/* check for class under test to have the desired state */
}
Run Code Online (Sandbox Code Playgroud)
在不太可能的情况下,您真的只想在指定时间内测试完成,即不关心操作是否抛出异常,您可以使用
@Test(timeout = 5000)
public void comletableFutureThenAccept() {
CompletableFuture<Void> future = someMethod();
future.exceptionally(t -> null).join();
}
Run Code Online (Sandbox Code Playgroud)
这用null结果替换了异常完成,因此join()不会抛出异常。所以只剩下超时。
Java 9 允许另一种选择,不使用 JUnit 的超时。
@Test()
public void comletableFutureThenAccept() {
CompletableFuture<Void> future = someMethod().orTimeout(5, TimeUnit.SECONDS);
future.join();
/* check for class under test to have the desired state */
}
Run Code Online (Sandbox Code Playgroud)
如果操作及时完成但后续验证需要更长的时间,这具有不会失败的优点。
| 归档时间: |
|
| 查看次数: |
1487 次 |
| 最近记录: |