This extension allows for creation of encapsulated test fixtures and their declarative use with JUnit5 Jupiter. Fixture5 helps in situation when test lasses need to
perform complex setup in @BeforeAll methods.
A fixture is simply a class extending TestFixture
class HttpClientFixture(store: ExtensionContext.Store) : TestFixture(store) {
override fun setup() {
// setup code here
}
override fun teardown() {
// teardown code here
}
}Fixture classes must adhere to the following
- The class has a single constructor matching that of
TestFixtureclass - The class implements
setupmethod - The class implements
teardownmethod
Fixtures can be employed in test by registering the FixtureExtension and using @Fixture annotation
@Fixture(HttpClientFixture::class)
@ExtendWith(FixtureExtension::class)
class HttpClientTest {
// test code here
}Fixtures are processed in order of declaration and for each fixture its setup method is called before all @BeforeAll methods.
Similarly, the teardown method for each fixture is called after all @AfterAll methods in reverse order (meaning fixture set up first is torn down last )
Fixtures can utilise a common store to either provide or consume objects of specified type
override fun setup() {
val engine = retrieve(Engine::class)
val plainClient = PlainHttpClient(engine)
val secureClient = AuthenticatedHttpClient(engine)
store(plainClient) // will be stored as PlainHttpClient::class
store(HttpClient::class, secureClient) // or declare provided type explicitly
}Objects provided by fixtures can also be injected into tests either via constructor or method parameters
@Fixture(BlockingEngine::class)
@Fixture(HttpClientFixture::class)
@ExtendWith(FixtureExtension::class)
class HttpClientTest(val client: HttpClient) {
@Test
fun `http client should use provided engine`(engine: Engine) {
assertTrue(client.engine === egine)
}
}Fixtures can be annotated with FixtureContext in order to declare (and enforce) their dependency requirements
@FixtureContext(requires = [ Engine::class ])
class HttpClientFixture(store: ExtensionContext.Store) : TestFixture(store) {
override fun setup() {
val engine = retrieve(Engine::class)
val secureClient = AuthenticatedHttpClient(engine)
store(HttpClient::class, secureClient)
}
override fun teardown() {
// teardown code here
}
}The following code will result in FixtureException due to missing dependency on Engine::class
@Fixture(HttpClientFixture::class)
@ExtendWith(FixtureExtension::class)
class HttpClientTest In similar fashion the extension checks that fixtures provide what they promise
@FixtureContext(
requires = [ Engine::class ],
provides = [ HttpClient::class ]
)
class HttpClientFixture(store: ExtensionContext.Store) : TestFixture(store) {
override fun setup() {
// nothing here
}
override fun teardown() {
// teardown code here
}
}Using such fixture will also lead to FixtureException
To install add the following dependency
Gradle
dependencies {
testImplementation("io.github.jcechace:fixture5:{latest_version}")
}Maven
<dependencies>
<dependency>
<groupId>io.github.jcechace</groupId>
<artifactId>fixture5</artifactId>
<version>{latest_version}</version>
<scope>test</scope>
</dependency>
</dependencies>