gpt4 book ai didi

java - 可完成的 future 。处理业务 "exceptions"的最佳方式是什么?

转载 作者:行者123 更新时间:2023-11-30 06:01:52 25 4
gpt4 key购买 nike

我刚刚开始熟悉 Java 的 CompletableFuture 工具。我创建了一个小玩具应用程序来模拟一些几乎所有开发人员都会遇到的重复用例。

在这个例子中,我只是想在数据库中保存一个东西,但在这样做之前我想检查一下这个东西是否已经保存。

如果事物已经在数据库中,则流程(可完成 future 链)应该停止并且不保存事物。我正在做的是抛出一个异常,以便最终我可以处理它并向服务的客户提供一个好的消息,这样他就可以知道发生了什么。

这是我到目前为止尝试过的:

首先是尝试保存事物的代码,如果事物已经在表中则抛出错误:

repository
.query(thing.getId())
.thenCompose(
mayBeThing -> {
if (mayBeThing.isDefined()) throw new CompletionException(new ThingAlreadyExists());
else return repository.insert(new ThingDTO(thing.getId(), thing.getName()));

这是我要运行的测试:

    CompletableFuture<Integer> eventuallyMayBeThing =
service.save(thing).thenCompose(i -> service.save(thing));
try {
eventuallyMayBeThing.get();
} catch (CompletionException ce) {
System.out.println("Completion exception " + ce.getMessage());
try {
throw ce.getCause();
} catch (ThingAlreadyExist tae) {
assert (true);
} catch (Throwable t) {
throw new AssertionError(t);
}
}

这种做法是我从这个回复中得到的:Throwing exception from CompletableFuture (投票最多的答案的第一部分)。

但是,这是行不通的。 ThingAlreadyExist 确实被抛出,但它从未被我的 try catch block 处理过。我的意思是,这个:

catch (CompletionException ce) {
System.out.println("Completion exception " + ce.getMessage());
try {
throw ce.getCause();
} catch (ThingAlreadyExist tae) {
assert (true);
} catch (Throwable t) {
throw new AssertionError(t);
}

永远不会执行。

我有两个问题,

  1. 有没有更好的办法?

  2. 如果不是,我是不是漏掉了什么?为什么我不能在我的测试中处理异常?

谢谢!

更新(06-06-2019)

谢谢 VGR,你是对的。这是有效的代码:

try {
eventuallyMayBeThing.get();
} catch (ExecutionException ce) {
assertThat(ce.getCause(), instanceOf(ThingAlreadyExists.class));
}

最佳答案

通过对包含在 Future 中的代码进行单元测试,您正在测试 java 的 Future 框架。您不应该测试库 - 您要么信任它们,要么不信任它们。

相反,单独测试您的代码是否在应该抛出正确的异常时抛出正确的异常。分解逻辑并对其进行测试。

您还可以对您的应用进行集成测试,以断言您的整个应用 行为正确(无论实现如何)。

关于java - 可完成的 future 。处理业务 "exceptions"的最佳方式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56469394/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com