我正在开发一个 Quarkus 项目,其中使用 Hibernate Reactive 和 Panache 进行非阻塞数据库操作。我的服务方法使用 Panache.withTransaction() 在事务内创建用户。
这是服务方法:
public Uni<Auth> createUser(Auth authRequest) {
User user = new User(authRequest);
String passwordHash = Password.hash(authRequest.getPassword()).withArgon2().getResult();
user.setPasswordHash(passwordHash);
return Panache.withTransaction(() -> PanacheEntityBase.persist(user))
.onItem().transform(success -> {
log.info("Successfully created user, email: {}", authRequest.getEmail());
return authRequest;
})
.onFailure(ConstraintViolationException.class)
.transform(ex -> {
log.error("User already exists, email: {}", user.getEmail());
throw new AccountDoesNotExistsException(Errors.ACCOUNT_ALREADY_EXISTS + user.getEmail());
});
}
这是我的测试用例:
package org.acme.service;
import io.quarkus.hibernate.reactive.panache.Panache;
import io.quarkus.hibernate.reactive.panache.PanacheEntityBase;
import io.quarkus.panache.mock.PanacheMock;
import io.quarkus.test.InjectMock;
import io.quarkus.test.TestReactiveTransaction;
import io.quarkus.test.junit.QuarkusTest;
import io.smallrye.mutiny.CompositeException;
import io.smallrye.mutiny.Uni;
import jakarta.inject.Inject;
import org.acme.entity.User;
import org.acme.model.Auth;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
@QuarkusTest
class AuthServiceTest {
private Auth authRequest;
@Inject
private AuthService authService;
@BeforeEach
void setUp() {
authRequest = new Auth();
authRequest.setEmail("[email protected]");
authRequest.setPassword("m)ck!123POwed");
authRequest.setFirstName("mock first name");
authRequest.setLastName("mcok last name");
PanacheMock.mock(User.class);
PanacheMock.mock(Panache.class);
}
@Test
void givenValidAuthRequest_whenCreateUserCalled_thenReturnAuthResponse() {
Mockito.when(Panache.withTransaction(any())).thenReturn(Uni.createFrom().item(authRequest));
Auth authResponse = authService.createUser(authRequest).await().indefinitely();
assertEquals(authRequest.getEmail(), authResponse.getEmail());
}
@Test
void givenValidAuthRequest_whenCreateUserCalled_thenThrowsException() {
Mockito.when(User.persist(any(User.class), any(Object.class))).thenReturn(Uni.createFrom().failure(new IOException("Mock exception")));
assertThrows(CompositeException.class, () -> authService.createUser(authRequest).await().indefinitely());
}
}
当我运行测试时,遇到以下错误:
No current Vertx context found
java.lang.IllegalStateException: No current Vertx context found
at io.quarkus.hibernate.reactive.panache.common.runtime.SessionOperations.vertxContext(SessionOperations.java:191)
at io.quarkus.hibernate.reactive.panache.common.runtime.SessionOperations.withSession(SessionOperations.java:110)
at io.quarkus.hibernate.reactive.panache.common.runtime.SessionOperations.withTransaction(SessionOperations.java:88)
at io.quarkus.hibernate.reactive.panache.common.runtime.WithTransactionInterceptor.intercept(WithTransactionInterceptor.java:20)
at io.quarkus.hibernate.reactive.panache.common.runtime.WithTransactionInterceptor_Bean.intercept(Unknown Source)
at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:42)
at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:30)
at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:27)
at org.acme.service.AuthService_Subclass.createUser(Unknown Source)
at org.acme.service.AuthService_ClientProxy.createUser(Unknown Source)
at org.acme.service.AuthServiceTest.givenValidAuthRequest_whenCreateUserCalled_thenReturnAuthResponse(AuthServiceTest.java:46)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at io.quarkus.test.junit.QuarkusTestExtension.runExtensionMethod(QuarkusTestExtension.java:973)
at io.quarkus.test.junit.QuarkusTestExtension.interceptTestMethod(QuarkusTestExtension.java:823)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
我尝试过的:
问题:
您可能缺少
io.quarkus.test.vertx.RunOnVertxContext
注释:
@Test
@RunOnVertxContext
public void givenValidAuthRequest_whenCreateUserCalled_thenReturnAuthResponse() {
...
}
您可以查看文档以获取完整示例。