skip to content

Embedded Instances

Starting the server inside the test process itself: a JUnit 4 rule or a JUnit 5 extension, a port taken at start-up, and a client bound to it. The fixed-port habit gets probed here.

on this pageshow

explore

questions

4

Why start an embedded WireMockServer with wireMockConfig().dynamicPort() instead of a fixed port?

level: middleimportance: must knowfreq 70%

answer

  1. a port is a shared machine resource
  2. do not name it, ask for one
  3. the value is unknown until start()
  4. read the base URL back at runtime
  5. the client under test must be configurable

basics

~20 s

A fixed port makes the fixture depend on a machine-wide resource nobody owns, so any other process already holding it fails the suite. dynamicPort() has WireMock take a free port at start-up, and the test reads the resolved address back.

solid answer

~50 s

Constructing an embedded server with no options binds WireMock's default port, and a fixed port is a claim on a machine-wide resource your test does not own. A leftover server from a run that crashed before `stop()`, a local development stack, or any other process on that number is enough to fail the suite with a bind error that says nothing about the test. `new WireMockServer(wireMockConfig().dynamicPort())` instead asks the operating system for a free ephemeral port when `start()` runs. The consequence is the part people miss: the port does not exist until start-up, so **nothing about it can be hardcoded**. The base URL has to be read back from the running instance and injected into the code under test — under `@WireMockTest` it arrives as a `WireMockRuntimeInfo` parameter — which means the client under test must take its upstream address as configuration rather than a constant.

code

java · 16 lines
java
@WireMockTest
class LadderStandingsClientTest {

    @Test
    void readsTheTaysideLadder(WireMockRuntimeInfo wm) {
        stubFor(get(urlPathEqualTo("/ladders/tayside-a/standings"))
            .willReturn(aResponse()
                .withStatus(200)
                .withBody("[{\"rink\":\"Frost\",\"points\":14}]")));

        // The port did not exist until the server started.
        LadderClient client = new LadderClient(wm.getHttpBaseUrl());

        assertEquals(14, client.standings("tayside-a").get(0).points());
    }
}

go deeper

for a junior

Know that an embedded WireMock server needs a port, that asking for a free one is the normal habit, and that the test must be told the resulting address rather than assuming it.

for a middle

Explain what WireMock's dynamicPort() does at start-up, why the resolved value cannot be known beforehand, and how a test obtains that value from the instance it started.

for a senior

Show how you would find and remove fixed ports across an inherited suite, and how you recognise a bind failure for what it is instead of retrying the job until it passes.

for a principal

Own the rule for the codebase: no fixture names a port, every client under test takes its upstream base URL as configuration, and say what you would enforce that with.

## The habit this question is probing An embedded WireMock instance has to listen somewhere, and the shortest thing to write is a number. A fixture that constructs `new WireMockServer()` with no options takes WireMock's default port; a fixture that writes a number in by hand takes whichever one somebody typed that afternoon. Either way the suite has staked a claim on a **machine-wide resource it does not own**. Nothing inside the test JVM can guarantee that claim: a leftover server from a run that crashed before `stop()` was reached, a local development stack, an unrelated tool, or a second copy of the same fixture is enough to lose it. The failure that follows is the worst kind, because it does not describe the problem. The suite dies during set-up with a bind error, the stack trace names the server rather than the test, and re-running the job sometimes works — which quietly teaches the team that the test is "flaky" rather than that the fixture is wrong. ## What dynamicPort() actually does `wireMockConfig()` builds WireMock's configuration object, and `dynamicPort()` on it says: do not name a port, ask the operating system for a free one. The request is made when `start()` runs, so the sequence is: 1. The fixture builds the configuration and constructs `new WireMockServer(wireMockConfig().dynamicPort())`. 2. `start()` binds, and the operating system hands back a free ephemeral port. 3. Only at that moment does the instance have an address. WireMock has a matching `dynamicHttpsPort()` on the same configuration object, with the same meaning for the HTTPS listener. ## The consequence people miss The port does not exist until start-up. That single fact rules out everything a fixed port made easy: - No constant in the test class can hold the URL. - No property file checked into the repository can hold it either. - Nothing may read the address **before** `start()` has returned. - The code under test cannot point at a hardcoded upstream and still be exercised by this fixture. So the resolved value has to travel from the running instance into the test at run time. In a JUnit 5 test annotated `@WireMockTest`, that is precisely what `WireMockRuntimeInfo` is for: the annotation starts the instance — taking a free port unless you tell it otherwise — and any test method that declares a `WireMockRuntimeInfo` parameter receives the resolved port and base URL. A fixture that constructs the server itself reads the same information back from the instance it started, after `start()`. ## What it forces on the code under test, and why that is good A client that can only talk to a constant address cannot be pointed at a stub at all. So making the port dynamic quietly forces the design most teams want anyway: the upstream base URL becomes a **constructor argument, a builder value or a configuration property** rather than a literal buried in the client. The curling-club ladder client stops containing a fixed `https://ladders.example` and starts taking whatever address it is given. That is the same shape that later lets it be pointed at a staging deployment, a recorded mapping set, or the real service, without touching the client at all. Worth saying out loud in an interview, because it reframes the answer from "avoid a port clash" to "the fixture and the production wiring want the same property". ## Diagnosing the fixed-port failure When you inherit a suite that still names ports, the tell is consistent: - It passes on one machine and fails on another with no difference in test logic. - It fails during set-up, before any assertion has had a chance to run. - The error mentions binding or an address already in use, not a stub or a match. - Leaving a stray process on that number reproduces it on demand, which is the cheapest confirmation available. The fix is mechanical rather than clever: move every fixture to WireMock's `wireMockConfig().dynamicPort()`, then follow the compiler and the failures to every place that assumed the old number — the client's default, a test property, a hand-written URL in an assertion. ## The neighbouring product In MockServer, `ClientAndServer.startClientAndServer()` called with no port argument does the same thing: it takes a free port when the in-process server starts, and the fixture reads the address back from the client it returns. ## What the interviewer is listening for - That you name WireMock's mechanism, `dynamicPort()`, and not just the advice. - That you know the value is unavailable until `start()` has returned. - That you can say how the address reaches the code under test, and what that requires of the client. - That you treat a bind failure as a design defect in the fixture rather than an unlucky run to be retried.

  • How does the code under test learn the address of a dynamically started embedded WireMock?
    It has to be told at run time. The test reads the resolved base URL from the running instance — under `@WireMockTest` that is the injected `WireMockRuntimeInfo` — and passes it into whatever the client uses for its target address: a constructor argument, a builder value, or a test property. The design consequence is that the client cannot hold a compile-time constant for its upstream, which is usually an improvement in its own right.
  • When is a fixed port on an embedded WireMock still defensible?
    Only when something outside your control cannot be told a different address — a tool that reads a checked-in configuration file, or a browser component pinned to one origin. Even then it is a liability you are accepting rather than a choice you would recommend, and the usual answer is to make that address configurable so the fixture can go back to taking a free port at start-up.

It is the difference between booking whichever sheet of ice is free tonight and insisting on sheet three. The second only works for as long as nobody else has the same idea.

saying these in an interview costs you the question

  • Hardcodes a port and calls the resulting failure flaky
  • Thinks WireMock's dynamicPort picks a random number in advance
  • Reads the port before calling start()
  • Points the code under test at a compile-time constant URL
  • Assumes a bind error means WireMock itself is misconfigured
open as a page

What replaces WireMock's WireMockRule when an embedded fixture moves from JUnit 4 to JUnit 5?

level: middleimportance: must knowfreq 58%

basics

~20 s

WireMockRule is WireMock's JUnit 4 integration, published in wiremock-junit4. On JUnit 5 you take wiremock-junit5 and use either the declarative @WireMockTest annotation, which injects a WireMockRuntimeInfo, or WireMockExtension when you need to configure the instance yourself.

open as a page

Which WireMock artifact do you declare to run an embedded stub server in a Java test?

level: juniorimportance: should knowfreq 64%

basics

~20 s

Declare the aggregate WireMock artifact, org.wiremock:wiremock, which pulls in the whole embedded library. WireMock 4 also publishes separate modules such as wiremock-core and wiremock-junit5 as an alternative for narrower dependencies. The old wiremock-jre8 artifact no longer exists.

open as a page

In WireMock 4, why does an embedded fixture's call to stubMapping.setRequest() no longer compile?

level: seniorimportance: should knowfreq 46%

basics

~20 s

WireMock 4 made its core data classes immutable and gave them builders, so the in-place setters on StubMapping are gone. Instead derive a new mapping: WireMock 4's StubMapping.transform takes a lambda that sets the request on a builder.

open as a page