Skip to content

jqwik-team/jqwik-micronaut

Folders and files

NameName
Last commit message
Last commit date
Jun 18, 2023
Jul 7, 2023
Jul 7, 2023
Apr 23, 2023
Apr 18, 2023
Mar 11, 2023
Mar 11, 2023
Jun 22, 2023
Jul 7, 2023
Jul 7, 2023
Jul 7, 2023
Jul 7, 2023
Apr 18, 2023

Repository files navigation

Java CI with Gradle

Jqwik Micronaut Support

This project provides an extension to support testing of Micronaut applications with Jqwik.

Loading
---
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

Table of Contents

How to Install

Gradle

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.

Maven

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>

Supported Micronaut Versions

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.

Standard Usage

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).

Lifecycle

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);
    }
}

Parameter Resolution of Autowired Beans

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();
    }
}

Micronaut JUnit Jupiter Testing Annotations

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.

Shortcomings

We are not aware of any at this time.

Release Notes

1.0.0

  • Uses jqwik 1.7.4.
  • Tested with Micronaut 3.8.9.