3

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?

SCM
  • 45
  • 1
  • 9
  • You could give a try on Spring Cloud Contracts. It's good when you've got to 'mock' a lot of information. It's SCC is built for this purpose. – Johnnes Souza Jul 03 '20 at 13:43
  • Well I don't have your context but if you see yourself doing too many or redundant setups, I would consider this as a smell on your way of testing. What are you testing? Do you need / care about all these setups? – Arnaud Claudel Jul 03 '20 at 13:53

2 Answers2

3

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": "john.doe@example.com"
  }
]

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

Abhinaba Chakraborty
  • 3,488
  • 2
  • 16
  • 37
1

I don't know which framework you are using. However if you have a spring-boot based application, you can put your stubs in seprate resource file and load it while running test.

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureWireMock(stubs="classpath:/stubs")
public class WiremockImportApplicationTests {

    @Autowired
    private Service service;

    @Test
    public void contextLoads() throws Exception {
        assertThat(this.service.go()).isEqualTo("Hello World!");
    }

}

Source : https://cloud.spring.io/spring-cloud-contract/reference/html/project-features.html#features-wiremock-registering-stubs

Katy
  • 1,023
  • 7
  • 19