JUnit 5 extensions and data type converters for Knot.x integration tests. Those tests allow to setup Knot.x instance with declared modules. It can be used both for module tests and regression tests.
Provides following helpers:
Knot.x-specific extension that manages test Vert.x instances (with Knot.x configuration injection) and WireMock servers (through KnotxWiremockExtension).
Example usage:
@ExtendWith(KnotxExtension.class)
public class ExampleIntegrationTest {
@ClasspathResourcesMockServer(port = 4001)
protected WireMockServer mockRepository;
@Test
@KnotxApplyConfiguration({"default.conf", "overloaded.conf"})
public void callModule_validKnotContextResult(VertxTestContext context, Vertx vertx) {
// ...
}
}
See more examples in ExampleKnotxJUnit5Test
.
See Vert.x JUnit 5 integration for guide
how to interact with VertxTestContext
instances. Also, under io.knotx.junit5.util.RequestUtil
there are some common methods that should make working with Vert.x tests contexts easier.
The annotation allows to specify one and more Knot.x configuration(s) to load for given test. It accepts a paths array and loads all configuration entries using Vert.x Config file stores, through a custom implementation enhanced with support for HOCON hierarchical configuration loading and cross-file variable references (for more details see KnotxConcatConfigProcessor reference). It supports two configuration semantics:
json
extension)conf
extension)The order of the configuration files is important, as it defines the overloading order (base file first, overrides last). For conflicting (identical) keys in configuration, configuration entries arriving last will overwrite the value provided by the previous configuration files.
See Vert.x Config overloading rules for more details.
KnotxApplyConfiguration annotation can be placed on class, method, and parameter level. As such, configuration for
parameter level will override method and class level, and method will override class level. For quick example see
test package namespace io.knotx.junit5.example
.
If you want to randomize a port for using inside your test, you can define a namespace inside your HOCON config:
test {
# random values generation section
random {
# all <name>.port entries will be substituted for different random ports
globalServer.port = 12345
actionAdapterService.port = 12345
}
}
(example taken from example_random_config.conf
file)
Then you can reference such variables from anywhere inside your configs; placeholder values will be substituted for real available port numbers:
@Test
@KnotxApplyConfiguration("config/example_random_config.conf")
public void injectRandomizedPort(@RandomPort Integer globalServerPort) {
// integer parameter will be filled with generated port from section 'random' for entry 'globalServer'
}
The working example is defined in io.knotx.junit5.examples.ExampleKnotxJUnit5Test#injectRandomizedPort
method from test classes.
Standalone WireMockServer injection and lifecycle management. Allows for:
Warning: if you use KnotxExtension, you must not inject KnotxWiremockExtension, as the functionality of the latter gets auto-imported into the former.
WireMockServer instances are recognized by their identifier - either test class instance variable name or test method parameter name.
For example below, two servers will be available for testWiremockRunningOnPort
method: mockServiceRandom
with randomly assigned port, and server
on port 3000
.
@ExtendWith(KnotxWiremockExtension.class)
public class WireMockTest {
private static final int MOCK_SERVICE_PORT_NUMBER = 3000;
@ClasspathResourcesMockServer // will be started on a random port
private WireMockServer mockServiceRandom;
@Test
public void testWiremockRunningOnPort(
@ClasspathResourcesMockServer(port = MOCK_SERVICE_PORT_NUMBER) WireMockServer server)
throws IOException, URISyntaxException {
// ...
}
}
One exception applies: one WireMockServer instance will be created per identifier within test given class:
@ExtendWith(KnotxWiremockExtension.class)
public class WireMockTest {
@ClasspathResourcesMockServer
private WireMockServer mockServiceRandom;
@Test
public void testWiremockEquality(
@ClasspathResourcesMockServer WireMockServer mockServiceRandom) {
assertTrue(this.mockServiceRandom == mockServiceRandom);
}
}
Only one WireMockServer instance with random port is created (mockServiceRandom
)
and injected both into instance field and method parameter.
With KnotxExtension, created WireMockServer instances' ports will be available
for referencing in Knot.x configuration under test.wiremock.<wiremockserver_identifier>.port
variables
(HOCON syntax only).
First we need to add Knot.x Junit5 to dependencies. We can get the module version from Knot.x Dependencies.
dependencies {
implementation(platform("io.knotx:knotx-dependencies:${project.version}"))
testImplementation(group = "io.knotx", name = "knotx-junit5")
testImplementation(group = "io.vertx", name = "vertx-junit5")
}
The KnotxExtension
and KnotxWiremockExtension
use parameters names to correctly initialize
injected fields and parameters (see @ClasspathResourcesMockServer
). It requires to compile modules with
tasks.withType(JavaCompile) {
options.compilerArgs << "-parameters"
}
Currently not supported due to unknown Knot.x internal error that ends up in a segfault. However, all required functionality
is implemented inside knotx-junit5
module.
Some simple examples are available in test package namespace io.knotx.junit5.example
.
For other use cases see following Knot.x projects that use this Knot.x JUnit5 module:
HoconLoader parses the HOCON configuration files and transforms all entries to JSON. This util is extremely helpful in Routing Handler's contract tests.
All feature requests and bugs can be filed as issues on Gitub. Do not use Github issues to ask questions, post them on the User Group or Gitter Chat.
Knot.x modules are licensed under the Apache License, Version 2.0 (the "License")