This project provides an extension to support testing of Spring and Spring-Boot applications with jqwik.
- How to Install
- Standard Usage
- Spring Boot
- Supported Spring / Spring Boot Versions
- Shortcomings
- Release Notes
Follow the
instructions here
and add the following dependency to your build.gradle
file:
dependencies {
implementation("org.springframework:spring-context:5.3.31")
...
testImplementation("net.jqwik:jqwik-spring:0.10.0")
testImplementation("org.springframework:spring-test:5.3.31")
}
You can look at a sample project using jqwik, Spring Boot and Gradle.
Follow the
instructions here
and add the following dependency to your pom.xml
file:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.31</version>
</dependency>
...
<dependency>
<groupId>net.jqwik</groupId>
<artifactId>jqwik-spring</artifactId>
<version>0.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.31</version>
<scope>test</scope>
</dependency>
You have to provide your own version of Spring or Spring Boot through Gradle or Maven. The jqwik-spring library has been tested with versions:
See supported versions for more details.
You need at least version 1.10.1
of the JUnit platform - otherwise
strange things could happen.
Keep in mind that if you are using Spring Boot you will have to
explicitly set the JUnit platform version.
To enable autowiring of a Spring application context or beans you just have to
add @JqwikSpringSupport
to your test container class:
import net.jqwik.api.*;
import net.jqwik.api.constraints.*;
import net.jqwik.api.lifecycle.*;
import net.jqwik.spring.*;
import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.test.context.*;
@JqwikSpringSupport
@ContextConfiguration(classes = MySpringConfig.class)
class MySpringProperties {
@Autowired
private MySpringBean mySpringBean;
@Property
void nameIsAddedToHello(@ForAll @AlphaChars @StringLength(min = 1) String name) {
String greeting = mySpringBean.sayHello(name);
Assertions.assertTrue(greeting.contains(name));
}
}
Configuration and autowiring of values is delegated to Spring's own test framework. Therefore all integration testing annotations can be used. This is also true for standard annotation support.
Spring will recreate its application context for each annotated class. That means, that
- 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 Spring-controlled beans.
If you want a property to recreate the app context for each try, you have to annotate
the property method with
@DirtiesContext
.
Compare the following two properties:
@JqwikSpringSupport
@ContextConfiguration(classes = MySpringConfig.class)
class MySpringProperties {
@Property(tries = 10)
void counterIsCountingUp(@Autowired MyCounter counter) {
counter.inc();
// Prints out 1, 2, 3 ... 10
System.out.println(counter.value());
}
@Property(tries = 10)
@DirtiesContext
void counterIsAlways1(@Autowired MyCounter counter) {
counter.inc();
// Prints out 1, 1, 1 ... 1
System.out.println(counter.value());
}
}
The class JqwikSpringLifecycleSupport
provides methods that can be used from
jqwik lifecycle hooks:
getApplicationContext(LifecycleContext)
returns an optional of the current Spring application context.
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:
@JqwikSpringSupport
@ContextConfiguration(classes = MySpringConfig.class)
class MyOtherSpringProperties {
@Autowired
MyOtherSpringProperties(MySpringBean springBean) {
Assertions.assertNotNull(springBean);
}
@BeforeProperty
void beforeProperty(@Autowired MySpringBean springBean) {
Assertions.assertNotNull(springBean);
}
@Property
void beanIsInjected(@Autowired MySpringBean springBean) {
Assertions.assertNotNull(springBean);
}
}
jqwik's Spring support is trying to mostly simulate how Spring's native Jupiter support works. Therefore, some of that stuff also works, but a few things do not.
By using @JqwikSpringSupport
as described above most - if not all - Spring Boot
testing features, e.g. test auto-configuration annotations should work.
Supports Java 17 and above.
5.2.15-RELEASE
5.3.31
6.1.0
2.6.15
2.7.17
3.2.0
Supports Java 8 and above.
5.2.15-RELEASE
5.3.31
2.6.15
2.7.17
Up to Spring version 5.2.15.RELEASE
, which comes with Spring Boot 2.3.12.RELEASE
,
the Spring extension and configuration is NOT handed down to inner test groups.
Also, member variables in the outer instance are not being auto wired
even if the inner class has all necessary annotations.
This is due to limitations of Spring's own testing framework
and cannot be fixed by this library.
- Added
JqwikSpringLifecycleSupport.getApplicationContext()
First version supporting Spring 3.x.
Requires Java 17 or above.
- Tested with Spring 5.3.31, 6.0.14, 6.1.0
- Tested with Spring Boot 2.6.15, 2.7.17, 3.0.12, 3.1.5, 3.2.0
Last version supporting Java 8 - 16.
- Upgrade to jqwik 1.8.2
- Upgrade to JUnitPlatform 5.10.1
- Tested with Spring 5.3.31
- Tested with Spring Boot 2.6.15, 2.7.17
- Upgrade jqwik 1.6.3
- Upgrade to JUnitPlatform 5.8.2
- Tested with Spring 5.3.14
- Tested with Spring Boot 2.6.2
- Upgrade jqwik 1.5.6
- Upgrade to JUnitPlatform 5.8.1
- Tested with Spring 5.3.11
- Tested with Spring Boot 2.5.5
- For Spring >= 5.3.0 test configuration is now "inherited" to
nested container classes annotated with
@Group
.
- Upgrade to jqwik 1.5.3
- Tested with more recent versions of Spring and Spring Boot