I have a simple reactive CRUD application made with Quarkus while following these two articles: Getting started reactive and Hibernate reactive panache
I am trying to test my service methods, but before that I’m trying to see how the example test works. This is the example test from the article:
import io.quarkus.test.hibernate.reactive.panache.TransactionalUniAsserter;
@QuarkusTest
public class SomeTest {
@Test
@RunOnVertxContext
public void testEntity(TransactionalUniAsserter asserter) {
asserter.execute(() -> new MyEntity().persist());
asserter.assertEquals(() -> MyEntity.count(), 1l);
asserter.execute(() -> MyEntity.deleteAll());
}
}
When I try to replicate the test like below, the test always passes no matter what I set the expected count to.
Here is my test file with the test case that is green.
`@QuarkusTest
@RunOnVertxContext
class AuthorServiceTest {
@Inject
AuthorService service;
@Test
@RunOnVertxContext
public void testGetAllAuthors(TransactionalUniAsserter a) {
a.execute(() -> new Author("J.K.", "Rowling", LocalDate.of(1965, 7, 31)).persist());
a.assertEquals(Author::count, 3L);
a.execute(Author::deleteAll);
}
}`
I am also trying to find out how to test service methods that return Uni types. I can’t find any resources online that show this. Most of the ways to test seem to throw No current Vertx context found.
Here is how my model looks like:
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Entity
@Table(name = "authors")
public class Author extends PanacheEntity {
@Column(nullable = false)
private String name;
@Column(nullable = false)
private String surname;
@Column(nullable = false)
private LocalDate dateOfBirth;
}
Here is my service:
import io.quarkus.hibernate.reactive.panache.Panache;
import io.quarkus.panache.common.Sort;
import io.smallrye.mutiny.Uni;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.ws.rs.core.Response;
import um.feri.model.Author;
import java.util.List;
@ApplicationScoped
public class AuthorService {
public Uni<List<Author>> getAllAuthors() {
return Author.listAll(Sort.by("surname"));
}
public Uni<Response> getAuthorById(Long id) {
return Author.findById(id)
.onItem().ifNotNull().transform(author -> Response.ok(author).build())
.onItem().ifNull().continueWith(() -> Response.status(Response.Status.NOT_FOUND).build());
}
public Uni<Author> findIfAuthorExists(Author author) {
return Author.find("name = ?1 and surname = ?2 and dateOfBirth = ?3",
author.getName(), author.getSurname(), author.getDateOfBirth())
.firstResult();
}
public Uni<Author> addAuthor(Author author) {
return findIfAuthorExists(author)
.onItem().ifNotNull().transform(existingAuthor -> existingAuthor)
.onItem().ifNull().switchTo(() -> Panache.withTransaction(author::persist).replaceWith(author));
}
public Uni<Response> updateAuthor(Long id, Author updatedAuthor) {
return Author.<Author>findById(id)
.onItem().ifNotNull().transformToUni(existingAuthor -> {
existingAuthor.setName(updatedAuthor.getName());
existingAuthor.setSurname(updatedAuthor.getSurname());
existingAuthor.setDateOfBirth(updatedAuthor.getDateOfBirth());
return Panache.withTransaction(existingAuthor::persist)
.replaceWith(Response.ok(existingAuthor).build());
})
.onItem().ifNull().continueWith(Response.status(Response.Status.NOT_FOUND).build());
}
public Uni<Response> deleteAuthor(Long id) {
return Panache.withTransaction(() -> Author.deleteById(id))
.map(deleted -> deleted
? Response.ok().status(Response.Status.NO_CONTENT).build()
: Response.ok().status(Response.Status.NOT_FOUND).build());
}
}
Is it better to just test the resource and leave the service methods alone?
The code for this project is available on my Github
I tried using this solution but every test passes, even if I compare 2 to 3;
I’ve changed a couple of things and now the test seems to work:
-
Upgrade Quarkus to 3.14.2. In the
pom.xml
:<properties> ... <quarkus.platform.version>3.14.2</quarkus.platform.version> ... </properties> <dependencies> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-hibernate-reactive-panache</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-rest</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-reactive-pg-client</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-rest-jackson</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-junit5</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>io.rest-assured</groupId> <artifactId>rest-assured</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.34</version> <scope>provided</scope> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-test-vertx</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-test-hibernate-reactive-panache</artifactId> <scope>test</scope> </dependency> </dependencies> ...
-
Remove
quarkus-reactive/src/test/java/um/feri/TransactionalUniAsserterInterceptor.java
and update the test to:package um.feri.services; import java.time.LocalDate; import org.junit.jupiter.api.Test; import io.quarkus.test.hibernate.reactive.panache.TransactionalUniAsserter; import io.quarkus.test.junit.QuarkusTest; import io.quarkus.test.vertx.RunOnVertxContext; import jakarta.inject.Inject; import um.feri.model.Author; @QuarkusTest class AuthorServiceTest { @Test @RunOnVertxContext public void testGetAllAuthors(TransactionalUniAsserter a) { a.execute( () -> new Author( "J.K.", "Rowling", LocalDate.of( 1965, 7, 31 ) ).persist() ); // Panache doesn't support method reference a.assertEquals( () -> Author.count(), 6L ); a.execute( () -> Author.deleteAll() ); } }
-
Optional, add
quarkus.hibernate-orm.log.sql=true
in theapplication.properties
. It will show you the SQL getting executed.
You should be able to test services the same way, for example:
@Inject
AuthorService service;
@Test
@RunOnVertxContext
@Order( 1 )
public void testGetAllAuthors(TransactionalUniAsserter a) {
a.execute( () -> new Author( "J.K.", "Rowling", LocalDate.of( 1965, 7, 31 ) ).persist() );
a.assertEquals( () -> Author.count(), 6L );
}
@Test
@RunOnVertxContext
@Order( 2 )
public void testService(TransactionalUniAsserter a) {
a.assertThat( () -> service.getAllAuthors(), authors -> {
Assertions.assertNotNull( authors );
Assertions.assertEquals( 6, authors.size() );
} );
}
0