Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practice how to manage a lot of wiremock stubs?

My unit tests use wiremock extensively and most of these test classes look like this:

class Test {

    private static WireMockServer wireMockServer;

    @BeforeAll
    static void setup() {
        wireMockServer = new WireMockServer(wireMockConfig().port(8080));
        wireMockServer.start();
    }

    @AfterAll
    static void teardown() {
        wireMockServer.stop();
    }

    @AfterEach
    void deleteScenariosAndRequests() {
        resetAllScenarios();
        resetAllRequests();
    }

    @Test
    void test1() throws {
        stubFor(post(urlEqualTo(SOME_URL))
            .willReturn(okJson("{}")));

        stubFor(post(urlEqualTo(SOME_OTHER_URL))
                .willReturn(okJson("{}")));

        stubFor(post(urlEqualTo(EVEN_ANOTHER_URL))
                .willReturn(okJson("{}")));

        //some action

        //some assertions
    }

    @Test
    void test2() {
        stubFor(post(urlEqualTo(SOME_URL))
                .willReturn(aResponse().withStatus(400)));

        stubFor(post(urlEqualTo(SOME_URL))
                .willReturn(aResponse().withStatus(400)));

        stubFor(post(urlEqualTo(SOME_URL))
                .willReturn(aResponse().withStatus(400)));

        //some action

        //some assertions
    }

}

So as you can see what I basically do is to define in each test the stubs that I actually need for this test.

Is this actual good pratice? I see myself repeating the same stubs again and again. On the other hand, there is the advantage that each test explicitly states what it needs.

Is there any commonly agreed best practice how to manage wiremock stubs in java unit tests?

like image 460
SCM Avatar asked Jan 25 '26 11:01

SCM


1 Answers

One way you can avoid repeatedly writing the same stubbings is by defining the stub location while creating the wiremock server in the setup step. You can store 100s of stubs in the folder and re-use them.

WireMock, when started programmatically, will default to src/test/resources as a filesystem root if not configured otherwise.

// Set the root of the filesystem WireMock will look under for files and mappings
.usingFilesUnderDirectory("/path/to/files-and-mappings-root")

// Set a path within the classpath as the filesystem root
.usingFilesUnderClasspath("root/path/under/classpath")

eg.

sample directory structure

A sample response json (src/test/resources/__files/api/v1/user.json)

[
  {
    "id": "795e19ed-ccae-4cf6-82c4-92fe9c8ac348",
    "accountId": "307dd105-2aef-483f-b85d-3c46045031d5",
    "firstName": "John",
    "lastName": "Doe",
    "email": "[email protected]"
  }
]

A sample mapping: (src/test/resources/mappings/api/v1/user-mapping.json)

{
  "request": {
    "method": "GET",
    "url": "/foo/api/v1/userProfiles?userIds=307dd105-2aef-483f-b85d-3c46045031d5,cb6fc0b3-4e99-4056-bbb4-c7ec6b240736,mock-completed-by-0"
  },
  "response": {
    "status": 200,
    "headers": {
      "Content-Type": "application/json"
    },
    "bodyFileName": "api/v1/user.json"
  }
}

On top of this, if you want to override the stubbed value for an API in some test case, then you just define that stub in your test case like you are doing currently. See this stub priority

like image 57
Abhinaba Chakraborty Avatar answered Jan 26 '26 23:01

Abhinaba Chakraborty



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!