This project provides an extension to support testing of Micronaut applications with Jqwik.
---
title: "Micronaut Test Extension for Jqwik: System Context"
---
flowchart TB
User["Software Engineer
[Person]
A software engineer willing to use
property-based testing along with
Java IoC frameworks"]
MTEJ["Micronaut Test Extension for Jqwik
[Software System]
Enables property-based testing
using Jqwik with Micronaut Test"]
MF["Micronaut Framework
[Software System]
Provides Micronaut
TestContext API"]
JQ["Jqwik
[Software System]
Provides test execution
lifecycle hooks API"]
User -- "Uses" --> MTEJ
MTEJ -- "Consumes API" --> MF
MTEJ -- "Consumes API" --> JQ
classDef focusSystem fill:#1168bd,stroke:#0b4884,color:#ffffff
classDef supportingSystem fill:#666, stroke:#0b4884,color:#ffffff
classDef person fill:#08427b,stroke:#052e56,color:#ffffff
class MTEJ focusSystem
class User person
class MF,JQ supportingSystem
click JQ "https://github.com/jqwik-team/jqwik" _blank
click MTEJ "https://github.com/jqwik-team/jqwik-micronaut" _blank
click MF "https://micronaut-projects.github.io/micronaut-test/latest/guide" _blank
Follow the instructions here and add the following dependency to your build.gradle
file:
dependencies {
implementation("io.micronaut:micronaut-context:3.8.9")
// ...
testImplementation("net.jqwik:jqwik-micronaut:1.0.0")
testImplementation("io.micronaut.test:micronaut-test-core:3.9.2")
}
You can look at a sample project TBD using Jqwik, Micronaut and Gradle.
Follow the instructions here and add the following dependency to your pom.xml
file:
<xml>
<dependency>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-context</artifactId>
<version>3.8.9</version>
</dependency>
<!--...-->
<dependency>
<groupId>net.jqwik</groupId>
<artifactId>jqwik-micronaut</artifactId>
<version>1.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.micronaut.test</groupId>
<artifactId>micronaut-test-core</artifactId>
<version>3.9.2</version>
<scope>test</scope>
</dependency>
</xml>
You have to provide your own version of Micronaut through Gradle or Maven. The jqwik-micronaut library has been tested with versions:
3.8.9
.
Please report any compatibility issues you stumble upon.
To enable autowiring of a Micronaut application context or beans you just have to add @JqwikMicronautTest
to your test container class:
import jakarta.inject.Inject;
import net.jqwik.api.ForAll;
import net.jqwik.api.Property;
import net.jqwik.api.constraints.AlphaChars;
import net.jqwik.api.constraints.StringLength;
import org.assertj.core.api.Assertions;
@JqwikMicronautTest
class MyMicronautProperties {
@Inject
private MyMicronautBean myMicronaut;
@Property(tries = 1)
void nameIsAddedToHello(@ForAll @AlphaChars @StringLength(min = 1) final String name) {
final String greeting = myMicronaut.sayHello(name);
Assertions.assertThat(greeting).contains(name);
}
}
Configuration and autowiring of values is delegated to Micronaut's own test framework and @JqwikMicronautTest
supports all parameters that @MicronautTest
comes with (see the Javadocs).
Micronaut will recreate its application context for each annotated class. That means:
- Singleton beans will only be created once for all tests of one test container class.
- Properties and tries within the same class share mutual state of all Micronaut-controlled beans.
By default, a property will recreate the app context for each try. If you want to change this, you have to use the property parameter perTry = true. For example:
import io.micronaut.test.annotation.TransactionMode;
import jakarta.inject.Inject;
import net.jqwik.api.Property;
import net.jqwik.api.lifecycle.AfterProperty;
import net.jqwik.api.lifecycle.BeforeProperty;
import net.jqwik.micronaut.JqwikMicronautTest;
import org.assertj.core.api.Assertions;
import javax.persistence.EntityManager;
@JqwikMicronautTest(transactionMode = TransactionMode.SINGLE_TRANSACTION, perTry = false)
class MyMicronautTest {
@Inject
private EntityManager entityManager;
@BeforeProperty
void setUpOne() {
final Book book = new Book();
book.setTitle("The Stand");
entityManager.persist(book);
}
@BeforeProperty
void setUpTwo() {
final Book book = new Book();
book.setTitle("The Shining");
entityManager.persist(book);
}
@AfterProperty
void tearDown() {
// check setups were rolled back. By default, Micronaut will rollback txs after tests execution.
final CriteriaQuery<Book> query = entityManager.getCriteriaBuilder().createQuery(Book.class);
query.from(Book.class);
Assertions.assertThat(entityManager.createQuery(query).getResultList()).isEmpty();
}
@Property(tries = 1)
void testPersistOne() {
final CriteriaQuery<Book> query = entityManager.getCriteriaBuilder().createQuery(Book.class);
query.from(Book.class);
Assertions.assertThat(entityManager.createQuery(query).getResultList().size()).isEqualTo(2);
}
@Property(tries = 1)
void testPersistTwo() {
final CriteriaQuery<Book> query = entityManager.getCriteriaBuilder().createQuery(Book.class);
query.from(Book.class);
Assertions.assertThat(entityManager.createQuery(query).getResultList().size()).isEqualTo(2);
}
}
Autowired beans will be injected as parameters in example and property methods, in all lifecycle methods and also in the test container class's constructor - if there is only one:
import jakarta.inject.Inject;
import net.jqwik.api.Property;
import net.jqwik.api.lifecycle.BeforeProperty;
import net.jqwik.micronaut.JqwikMicronautTest;
import org.assertj.core.api.Assertions;
import org.springframework.beans.factory.annotation.Autowired;
@JqwikMicronautTest
class MyOtherMicronautTest {
@Inject
MyOtherMicronautTest(final AppBean appBean) {
Assertions.assertThat(appBean).isNotNull();
}
@BeforeProperty
void injectStatic(final AppBean appBean) {
Assertions.assertThat(appBean).isNotNull();
}
@Property(tries = 1)
void testPropertyInjected(final AppBean appBean) {
Assertions.assertThat(appBean).isNotNull();
}
}
jqwik's Micronaut support is trying to mostly simulate how Micronaut's native Jupiter support works. Therefore, some of that stuff also works, but a few things do not.
We are not aware of any at this time.
- Uses jqwik 1.7.4.
- Tested with Micronaut 3.8.9.