Skip to content

cui-test-mockwebserver-junit5

What is it?

A junit 5 extension for MockWebServer providing some convenience, compared to the original.

Maven Coordinates

    <dependency>
        <groupId>de.cuioss.test</groupId>
        <artifactId>cui-test-mockwebserver-junit5</artifactId>
        <!-- Use the latest release; see the Maven Central badge above -->
        <version>x.y.z</version>
    </dependency>

Using MockWebServer

The MockWebServer extension provides a simple way to test HTTP/HTTPS interactions in your application. It allows you to configure mock responses for specific endpoints and verify that your code correctly handles these responses.

Happy Path Example

Here’s a basic example showing how to use the MockWebServer extension with both @MockResponseConfig and @ModuleDispatcher annotations:

@EnableMockWebServer(useHttps = true)
class MockWebServerTest {

    @Test
    @DisplayName("Should handle GET request with @MockResponseConfig")
    @MockResponseConfig(
        path = "/api/users",
        method = HttpMethodMapper.GET,
        jsonContentKeyValue = "users=[]",
        status = 200
    )
    void shouldHandleGetRequest(URIBuilder uriBuilder, SSLContext sslContext) throws IOException {
        // Create HttpClient with the injected SSL context
        HttpClient client = HttpClient.newBuilder()
                .sslContext(sslContext)
                .build();

        // Create request to the configured endpoint
        HttpRequest request = HttpRequest.newBuilder()
                .uri(uriBuilder.addPathSegment("api").addPathSegment("users").build())
                .GET()
                .build();

        // Send request
        HttpResponse<String> response = client.send(request,
                HttpResponse.BodyHandlers.ofString());

        // Verify response
        assertEquals(200, response.statusCode());
        assertEquals("{\"users\":[]}", response.body());
    }

    @Test
    @DisplayName("Should handle POST request with @ModuleDispatcher")
    @ModuleDispatcher
    void shouldHandlePostRequest(URIBuilder uriBuilder, SSLContext sslContext) {
        // Send POST request to the endpoint configured by getModuleDispatcher()
        // ...
    }

    // The bare @ModuleDispatcher on the test method defers to this method to obtain the dispatcher
    ModuleDispatcherElement getModuleDispatcher() {
        var dispatcher = new BaseAllAcceptDispatcher("/api/posts");
        dispatcher.setMethodToResult(new mockwebserver3.MockResponse.Builder()
                .code(201)
                .addHeader("Content-Type", "application/json")
                .body("{\"id\":\"123\",\"status\":\"created\"}")
                .build(), HttpMethodMapper.POST);
        return dispatcher;
    }
}

Parameter Resolvers

The MockWebServer extension provides several parameter resolvers that can inject useful objects into your test methods:

Parameter Type Description

MockWebServer

The actual MockWebServer instance that can be used to configure responses, check received requests, etc.

URIBuilder

A utility for building URIs that point to the MockWebServer instance. The builder is pre-configured with the server’s host, port, and scheme.

SSLContext

When HTTPS is enabled, this provides access to the SSL context used by the server.

Example of using multiple parameter resolvers:

@EnableMockWebServer(useHttps = true)
class ParameterResolverTest {

    @Test
    @DisplayName("Should inject multiple parameters")
    void shouldInjectMultipleParameters(
            MockWebServer server,
            URIBuilder uriBuilder,
            SSLContext sslContext) {

        // All parameters are automatically injected
        assertNotNull(server);
        assertNotNull(uriBuilder);
        assertNotNull(sslContext);

        // URIBuilder is configured with server details
        assertEquals(server.getPort(), uriBuilder.getPort());
        assertEquals("https", uriBuilder.build().getScheme());
    }
}

URIBuilder Usage Tips

When building URIs with multiple path segments, prefer using the addPathSegments method instead of chaining multiple addPathSegment calls:

// RECOMMENDED - Use addPathSegments for multiple path segments
URI uri = uriBuilder.addPathSegments("api", "users", "123").build();

// Less efficient approach
URI uri = uriBuilder.addPathSegment("api").addPathSegment("users").addPathSegment("123").build();

Using with WeldUnit

If you use unit-testing with WeldUnit, the parameter resolution might fail because of WeldUnit trying to resolve the corresponding Parameter, without knowing how to resolve it. In that cases, you can use @ExplicitParamInjection on method or class.

@MockResponseConfig Annotation

The @MockResponseConfig annotation allows you to define mock responses for specific paths and HTTP methods. It can be applied at the class or method level and is repeatable.

For detailed information about using @MockResponseConfig, including the new context-aware behavior, see Working with @MockResponse.

@ModuleDispatcher Annotation

The @ModuleDispatcher annotation provides more flexibility for configuring complex request handling logic.

For detailed information about using @ModuleDispatcher and implementing the ModuleDispatcherElement interface, see Working with @ModuleDispatcher and ModuleDispatcherElement.

@EnableMockWebServer Options

The @EnableMockWebServer annotation supports several configuration options:

HTTP Mode (Default)

@EnableMockWebServer(useHttps = false)
class HttpModeTest {
    // ...
}

Manual Server Start

@EnableMockWebServer(useHttps = true, manualStart = true)
class ManualStartTest {

    @Test
    void shouldStartServerManually(MockWebServer server, URIBuilder uriBuilder) {
        // Here we need the MockWebServer parameter to control server lifecycle

        // Server is not started automatically
        assertFalse(server.getStarted());

        // Start the server manually
        server.start();

        // Now the server is running
        assertTrue(server.getStarted());

        // The injected URIBuilder resolves the server URL lazily, so it now builds valid URIs
        URI uri = uriBuilder.addPathSegment("api").build();
        assertEquals(server.getPort(), uri.getPort());

        // Manual closing is unnecessary: the extension closes the server in its afterEach callback.
    }
}

Manual Server Start Considerations

When using manualStart = true, the injected URIBuilder binds its base URL lazily:

  • The base URL is resolved from the server the first time you call build(), not at injection time

  • You can therefore use the injected URIBuilder directly, as long as you start the server before building any URI

  • There is no need to create a separate URIBuilder after starting the server

// CORRECT - start the server first, then build from the injected URIBuilder
server.start();
URI uri = uriBuilder.addPathSegment("api").build();

// INCORRECT - building before the server is started cannot resolve the base URL yet
URI uri = uriBuilder.addPathSegment("api").build(); // server not started

HTTPS Support and Certificates

For detailed information about using HTTPS with the MockWebServer extension and configuring certificates for testing, see HTTPS Support and Certificates.

Migration Guide

For detailed information about migrating from older versions of the MockWebServer extension to the current version, see Migration Guide.

About

A junit 5 extension for MockWebServer providing some convenience, compared to the original

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Used by

Contributors

Languages