Quarkus WireMock

Quarkus WireMock extension for tests and local development. This extension starts WireMock as a Dev Service, thus it is designed to run in dev and test mode only!

Installation

If you want to use this extension, you need to add the io.quarkiverse.wiremock:quarkus-wiremock dependency to your build file first.

For instance, with Maven, add the following dependency to your POM file:

<dependency>
    <groupId>io.quarkiverse.wiremock</groupId>
    <artifactId>quarkus-wiremock</artifactId>
    <version>1.7.0</version>
    <scope>provided</scope>
</dependency>

Usage

The extension comes with most reasonable defaults.

quarkus.wiremock.devservices.enabled=true
quarkus.wiremock.devservices.reload=true
quarkus.wiremock.devservices.files-mapping=src/test/resources
quarkus.wiremock.devservices.global-response-templating=false
Due to its build time nature is totally fine that Quarkus prints unrecognized configuration key warnings when executing integration tests.
Starting the WireMock Dev Service doesn’t automatically redirect your @RestClient calls to it; see Redirecting REST Clients to WireMock below.

Testing

Stubbing & Verifying

A core feature of WireMock is the ability to return HTTP responses for request matching criteria. You can configure stubs using JSON configuration files placed in the mappings and __files folders. The root location of these folders can be defined via quarkus.wiremock.devservices.files-mapping. By default the root location points to src/test/resources.

In addition, you might want to configure WireMock’s stubbing and request matching behavior programmatically. To do so, please add the following dependency to your target project:

<dependency>
    <groupId>io.quarkiverse.wiremock</groupId>
    <artifactId>quarkus-wiremock-test</artifactId>
    <version>1.7.0</version>
    <scope>test</scope>
</dependency>

After that, a WireMock client reference can be injected along with your test execution lifecycle as shown below:

@QuarkusTest
@ConnectWireMock
class WireMockDevServiceResourceTest {

    private static final String MOCK_MSG = "Hello from WireMock!";

    WireMock wiremock; // will be injected automatically when the test class is annotated with @ConnectWireMock

    @Test
    void testHelloEndpoint() {
        Assertions.assertNotNull(wiremock);
        wiremock.register(get(urlEqualTo("/mock-me"))
            .willReturn(aResponse().withStatus(200).withBody(MOCK_MSG)));
        ...
    }

}
For more details please refer to the WireMock Stubbing & Verifying docs.

Redirecting REST Clients to WireMock

By default, starting the WireMock server does not rewire your application’s outgoing calls to go through it. If you’re using a MicroProfile/Quarkus @RestClient, you still need to point its base URL at the WireMock Dev Service for your requests to actually reach it and match your stubs.

The easiest way is to set the restClient attribute of @ConnectWireMock:

@QuarkusTest
@ConnectWireMock(restClient = "my-api") (1)
class WireMockDevServiceResourceTest {

    private static final String MOCK_MSG = "Hello from WireMock!";

    WireMock wiremock;

    @RestClient
    MyApiClient myApiClient; (2)

    @Test
    void testHelloEndpoint() {
        wiremock.register(get(urlEqualTo("/mock-me"))
            .willReturn(aResponse().withStatus(200).withBody(MOCK_MSG)));

        assertEquals(MOCK_MSG, myApiClient.hello()); (3)
    }

}
1 my-api must match the configured name of your REST client (i.e. as used in quarkus.rest-client.my-api.url, or the client’s @RegisterRestClient(configKey = "my-api")).
2 No manual configuration needed: the client’s base URL is redirected to WireMock automatically for the duration of the test.
3 Requests now reach WireMock instead of the real downstream API, so your registered stubs get matched.

restClient is left empty by default, since an application can have multiple REST clients and only some of them may need to be redirected to WireMock in a given test. @ConnectWireMock is repeatable, so redirect more than one REST client by repeating it:

@QuarkusTest
@ConnectWireMock(restClient = "my-api")
@ConnectWireMock(restClient = "my-other-api")
class WireMockDevServiceResourceTest {
    ...
}

If you’d rather configure this yourself (e.g. you need more control, or you’re not using @ConnectWireMock), you can set the client’s URL manually, typically in a test-only properties file (e.g. src/test/resources/application.properties):

quarkus.rest-client.my-api.url=http://localhost:${quarkus.wiremock.devservices.port}

Configuration retrieval

This Quarkus extension exposes configuration keys via Java constants (WireMockConfigKey). By doing so, the config values can be accessed more easily:

@QuarkusTest
class WireMockDevServiceResourceTest {

    // WireMockConfigKey is provided by the core module and does not require the `test` module dependency
    @ConfigProperty(name = WireMockConfigKey.PORT)
    Integer port; // the port WireMock server is listening on

}

You can even access the WireMock Dev Service configuration values from within a Quarkus Integration Test:

@QuarkusIntegrationTest
@ConnectWireMock
class WireMockDevServiceResourceTest {

    DevServicesContext devServicesContext;

    @Test
    void testWireMockDevServiceConfigPropagation() {
        // Dev Service config gets propagated and is accessible via the ConfigProvider API
        int port = ConfigProvider.getConfig().getValue(WireMockConfigKey.PORT, Integer.class);

        // or via the Dev Service Context
        int portDevSerCtx = Integer.parseInt(devServicesContext.devServicesProperties().get(WireMockConfigKey.PORT));
        ...
    }

}
Please be aware that Dependency Injection (DI) works for specific types (DevServicesContext and WireMock) only. The latter in particular is only available if the class has been annotated with @ConnectWireMock.

You can also reuse a @QuarkusTest as a @QuarkusIntegrationTest where applicable:

@QuarkusIntegrationTest
public class WireMockDevServiceResourceIT extends WireMockDevServiceResourceTest {
    // re-use Quarkus tests as integration tests
}

Further more this extension supports the configuration capabilities of Quarkus. This means you can reference WireMock configuration keys within your custom properties via variable interpolation.

custom.config.wiremock.url=http://localhost:${quarkus.wiremock.devservices.port}/mock-me
Please refer to Property Expressions for further details.

Logging

The verbosity of the WireMock log output can be controlled through:

quarkus.log.category."io.quarkiverse.wiremock.devservice.WireMockServer".level=ERROR

Extension Configuration Reference

Configuration property fixed at build time - All other configuration properties are overridable at runtime

Configuration property

Type

Default

If Dev Services for WireMock has been explicitly enabled or disabled.

Environment variable: QUARKUS_WIREMOCK_DEVSERVICES_ENABLED

boolean

true

Restart WireMock Dev Service whenever Quarkus is reloaded. Otherwise, whenever files are changed in the files-mapping location you would need to restart the Dev Service (WireMock server) manually.

Environment variable: QUARKUS_WIREMOCK_DEVSERVICES_RELOAD

boolean

true

Optional fixed port the WireMock Dev Service will listen to. If not defined, the port will be chosen randomly.

WARNING: Only ports between 1025 and 65535 are permitted.

Environment variable: QUARKUS_WIREMOCK_DEVSERVICES_PORT

int

Path to the WireMock configuration files (root dir which contains the mappings and __files folders). If this starts with classpath: then files will be looked up on the classpath instead of the filesystem.

Environment variable: QUARKUS_WIREMOCK_DEVSERVICES_FILES_MAPPING

string

src/test/resources

Response templating is enabled by default in WireMock 3, with this setting response templating can be enabled globally.

Please refer to Response Templating for more details.

Environment variable: QUARKUS_WIREMOCK_DEVSERVICES_GLOBAL_RESPONSE_TEMPLATING

boolean

false

Control whether WireMock Extension service loading, is enabled.

Environment variable: QUARKUS_WIREMOCK_DEVSERVICES_EXTENSION_SCANNING_ENABLED

boolean

false