我一直在将一些代码转换为异步代码。原来的单元测试使用了注解@Test(expected = MyExcpetion.class)
但我认为这不会起作用,因为我想要断言的异常被包装在java.util.concurrent.ExcutionException
。我确实尝试过这样称呼我的未来,但我的断言仍然失败,我不喜欢我必须添加return null
myApiCall.get(123).exceptionally((ex) -> {
assertEquals(ex.getCause(),MyCustomException.class)
return null
}
我也尝试过这个味道,但还是不行
myApiCall.get(123).exceptionally((ex) -> {
assertThat(ex.getCause())
.isInstanceOF(MyException.class)
.hasMessage("expected message etc")
return null;
}
如果找不到 id,我的 API 就会抛出异常。我应该如何正确测试这个?我可以使用原来的注释吗?
我的 api 调用在运行时会到达数据库。在这个测试中,我将我的 future 设置为返回错误,因此它实际上不会尝试与任何东西进行通信。被测试的代码如下所示
public class myApiCall {
public completableFuture get(final String id){
return myService.getFromDB(id)
.thenApply(
//code here looks at result and if happy path then returns it after
//doing some transformation
//otherwise it throws exception
)
}
}
在单元测试中我强制myService.getFromDB(id)
返回错误数据,以便我可以测试异常,并保持单元测试不接触数据库等。
假设您的 API 在调用时会抛出异常0
:
public static CompletableFuture<Integer> apiCall(int id) {
return CompletableFuture.supplyAsync(() -> {
if (id == 0) throw new RuntimeException("Please not 0!!");
else return id;
});
}
您可以使用以下代码测试它是否按预期工作(我正在使用 TestNG,但我怀疑将其转换为 JUnit 测试不会太困难):
@Test public void test_ok() throws Exception {
CompletableFuture<Integer> result = apiCall(1);
assertEquals(result.get(), (Integer) 1);
}
@Test(expectedExceptions = ExecutionException.class,
expectedExceptionsMessageRegExp = ".*RuntimeException.*Please not 0!!")
public void test_ex() throws Throwable {
CompletableFuture<Integer> result = apiCall(0);
result.get();
}
请注意,第二个测试使用的事实是 ExecutionException 消息将包含原始异常类型和消息,并使用正则表达式捕获期望。如果你不能用 JUnit 做到这一点,你可以调用result.get()
在 try/catch 块中并调用throw e.getCause();
在 catch 块中。换句话说,是这样的:
@Test(expectedExceptions = RuntimeException.class,
expectedExceptionsMessageRegExp = "Please not 0!!")
public void test_ex() throws Throwable {
CompletableFuture<Integer> result = apiCall(0);
try {
result.get();
} catch (ExecutionException e) {
throw e.getCause();
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)