我有一个非常混乱的问题,以下夸克/冬眠-反应/叛变。首先,我将描述我在Quarkus中使用hibernate实现的特性--反应性和变体。
任务是从数据库中检索一条记录,
Uni<MyRecord> getAuthenticationRecord(String id);然后在对象中使用refresh_token字段并构建一个请求对象,并将其传递给返回CallableFuture的第三方API。
CompletableFuture<TokenResponse> refreshToken(final TokenRequest tokenRequest);最后,将这些值从tokenRequest中删除,并更新步骤a中检索的记录。
我尝试了以下几点:
class MyApi {
public Uni<AuthRecord> refreshToken(String owner) {
MyRecord authRecord = getAuthenticationRecord(owner); //get the authentication record
TokenResponse refreshToken = authRecord.onItem().transform(MyRecord::refreshToken)
.chain(refreshToken -> {
TokenRequest request = new TokenRequest(refreshToken); //create the request object
return Uni.createFrom().completionStage(refreshToken(request)); //convert the CallableFuture to Uni
});
//Join the unis and update the auth record
return Uni.combine().all().unis(authRecord, refreshToken).asTuple().onItem().transform(
tuplle -> {
var record = tuple.getItem1();
var refresh = tuple.getItem2();
record.setCode(refresh.getToken());
return record.persistAndFlush();
}
);
}
}在测试用例中使用它:
@Inject
MyApi api;
@Test
public void test1() {
//This produces nothing
api.refreshToken("owner").subscribe().with(
item -> {
System.out.println(Json.encode(item));
}
)
}
@Test
public void test2() {
//This won't work because no transaction is active
var record = api.refreshToken("owner").await().indefinitely();
}
@Test
@ReactiveTransactional
public void test3() {
//This won't work either because the thread is blocked @Blocking annotation didn't help either
var record = api.refreshToken("owner").await().indefinitely();
}有什么建议吗?
发布于 2022-06-21 16:56:20
你可以test reactive applications using quarkus-test-vertx
quarkus-test-vertx依赖项: io.quarkus quarkus test -vertx test 现在您可以访问Assertions.assertThat(authRecord).isNotNull();:@Inject MyApi api;@Test @TestReactiveTransaction公共voidtest1(UniAsserter断言者){ asserter.assertThat( () -> api.refreshToken("owner"),authRecord -> MyApi );}
@TestReactiveTransaction将在反应性事务中运行测试,并在事务结束时回滚事务。这也将对在vertx事件循环线程中运行整个测试产生影响。
如果不希望在结束时回滚事务,可以使用Panache.withTransaction和@RunOnVertxContext启动自己的事务:
@Test
@RunOnVertxContext // Makes sure that the whole test runs in a Vert.x event loop thread
public void test1(UniAsserter asserter) {
asserter.assertThat(
() -> Panache.withTransaction(() -> api.refreshToken("owner")),
authRecord -> Assertions.assertThat(authRecord).isNotNull();
); 如果我正确地理解了其余的代码,那么authRecord和refreshToken已经被一个接一个地链接起来了。我不认为你需要combine.all:
class MyApi {
public Uni<AuthRecord> refreshToken(String owner) {
return getAuthenticationRecord(owner)
.chain(authRecord -> authRecord
.map(MyRecord::refreshToken)
.chain(refreshToken -> {
TokenRequest request = new TokenRequest(refreshToken); //create the request object
return Uni.createFrom().completionStage(refreshToken(request)); //convert the CallableFuture to Uni
})
.chain( refreshToken -> {
authRecord.setCode(refresh.getToken());
return authRecord.persistAndFlush();
})
);
}
}使用方法参考,它变成:
return getAuthenticationRecord(owner)
.chain(authRecord -> authRecord
.map(MyRecord::refreshToken)
.map(TokenRequest::new)
.map(this::refreshToken)
.chain(Uni.createFrom()::completionStage)
.chain(refreshToken -> {
authRecord.setCode(refresh.getToken());
return authRecord.persistAndFlush();
})
);
}https://stackoverflow.com/questions/71001520
复制相似问题