I'm trying to learn some new things using Quarkus, and I kinda got stuck on something:
I want to create some tests that are self sustained, I mean, I should be able to run each one independently of each other.
I'm using Testcontainers(PostgreSQL) to run some component tests, but I would like to each @Test be able to run on a 'clean database', but I don't think that stoping the container and starting it once again for each @Test would be a good idea. I could have a @BeforeEach(container.dropColumn()) or @BeforeEach(container.truncateColumn()) but: 1 - I don't know if this is the better way, 2 - I don't know how to do this.
Given an hypothetical test scenario:
Scenario 1 - Pass
Scenario 2 - Fail
The second test fail because the data from the first scenario is still on the database. Here, some code to help.
resources
@Inject
UserService userService;
@POST
@Transactional
public Response saveUser(@Valid UserDto user){
return Response.status(Response.Status.CREATED)
.entity(userService.saveUser(user, user.getPassword())).build();
}
@GET
public Iterable<User> findAll(){
return userService.findAll();
}
tests
@Test
void shouldSuccessfullyCreateUser(){
User mockUser = MockUser.onlyMandatoryFields() //MockUser
given()
.body(mockUser)
.contentType(ContentType.JSON)
.when()
.post("/users").prettyPeek()
.then()
.statusCode(Response.Status.CREATED.getStatusCode());
@Test
void shouldHaveAnEmptyDatabase(){
User[] userList = given()
.contentType(ContentType.JSON)
.when()
.get("/users").prettyPeek()
.then()
.extract()
.response()
.as(User[].class);
assertEquals(0, userList.length);
}
I've already tried @TestTransaction as described in Quarkus Docs but no success.
I was looking for something like @DirtiesContext from Spring.
Anyway, I've got an open repository, if you want to look further into the code. The tests can be found here.
@TestTransaction works properly when you test repositories or CDI beans directly.
I've already tried
@TestTransactionas described in Quarkus Docs, but no success.
It works if tests run in the same transaction context as the tested code.
Your REST resource works under a different transaction context than your test method; therefore, @TestTransaction will not work in your case. In your case the transaction gets committed at the end of the rest call; hence you cannot rollback it.
See an example of a working test validating the repository directly.
@Test
@TestTransaction
void shouldFail_whenCreatingNewLedgerWithUnrecognizedType() {
//when/then
assertThatThrownBy(() -> customSqlRepository.insertWithUnrecognizedType())
.isInstanceOf(PersistenceException.class)
.hasMessageContaining("Check constraint violation")
.hasMessageContaining("LEDGER_ACCOUNT_TYPE IN(");
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With