Integration of WireMock & Spring REST Docs

636 views
Skip to first unread message

Oliver Trosien

unread,
May 31, 2016, 12:08:52 PM5/31/16
to wiremock-user
Hi wiremock-user list,

I'd like to shamelessly ;-) advertise our newly open-sourced project [1] integrating Spring REST Docs (http://projects.spring.io/spring-restdocs/) with WireMock. The idea behind the integration is to auto-generate WireMock (json) stubs as part of the server test suite and publish these stubs to an artifact repository. Clients can use these stubs to verify their client contract against them. It's still at a very early stage, but already quite useable, especially if you think about microservices communicating over REST.

I'd be happy for your feedback.

There is one thing I did not manage yet, but maybe there is a known solution. When I generate multiple stubs for the same urlPath (for example one error and one success case), there is no way for the client to pick one specific stub. I was thinking about naming the stubs, but all I found in the docs was assigning a priority, which I would have to set while generating them on the server - which obviously is not what I want. Does anyone have an idea for this?

Regards,
 Oliver

[1] https://github.com/ePages-de/restdocs-wiremock

Tom Akehurst

unread,
May 31, 2016, 12:27:03 PM5/31/16
to wiremock-user
Hi Oliver,

Shameless advertising of useful tools is most welcome! I'll definitely be taking a look at this.

In the case you've described, where two generated stubs have the same URL, how would the actual service distinguish what needs to be returned? Is it purely the system's state, or some other property of the request like cookies, request body, headers etc.?

If it's purely system state, then the Scenarios feature of WireMock might be what you're after. This models a state machine, so that the response for a given request can change as the state advances, and state changes can be triggered by specific requests. As a concrete example, a GET to /todo/items could start by returning an empty array, then a POST to /todo/items could update the scenario state so that the next GET would return a single item.

On the other hand, if responses are to be differentiated by properties of the request other than the URL, then I guess it's simply a case of adding this to your generation logic. WireMock's record/playback feature has the ability to select which headers are included in the request pattern - maybe this is a useful template.

Oliver Trosien

unread,
Jul 1, 2016, 8:43:47 AM7/1/16
to wiremock-user
Hi Tom, hi WireMock Users,

thanks a lot for your prompt request. You're right, I probably want to use the scenario feature to differentiate between different states on the server. While digging deeper, I also found a different solution. I can also load a subset of the total set of json mappings per test case. So on the client side the user is able to read in only the json stubs required for his expected scenario.

This lead me to building a spring-boot-starter for WireMock, which now becomes another shameless plug for the users of this list ;-) (At the moment also hosted in the same repository, see https://github.com/ePages-de/restdocs-wiremock)

Here is an example of using WireMock using the starter:

@RunWith(SpringJUnit4ClassRunner.class) // (1)
@SpringApplicationConfiguration(classes = { ClientApplication.class }) // (2)
@ActiveProfiles("test") // (3)
@WireMockTest(stubPath = "wiremock/restdocs-server") // (4) 
public class NoteServiceTest {

    @Autowired
    private WireMockServer wireMockServer; // (5)
    ...
 }
  1. Use Spring's JUnit Runner (as of 1.4.0 this will be called SpringRunner), for this is an integration test.
  2. Include the usual application configuration classes
  3. Extend your test with properties to point to your WireMock server. In the example in our github repo, we are using a Spring Expression inside application-test.properties to point our service to WireMock by setting: service.baseUri=http://localhost:${wiremock.port}/
  4. The @WireMockTest annotation enables the wireMockServer bean, which can be accessed from your test's application context. By default, it starts a WireMockServer on a dynamic port, but you could also set it to a fixed port. The stubPath property can be used to point to a classpath resource folder that holds your json stubs.
  5. If you want, you can auto-wire the WireMockServer instance, and re-configure it, just as described in the official WireMock documentation.

As mentioned above, it is possible to read-in a subset of mappings for each test, by repeating the `@WireMockTest` annotation on the test method.
The stubPath is concatenated from the values given on the test class and the test method, just as a `@RequestMapping` annotation in Spring would.
In the example given below, the resulting stubPath provided to WireMock is composed as `wiremock/myservice/specific-mappings`.

@WireMockTest(stubPath = "wiremock/myservice")
public class MyTest {
    @Test
    @WireMockTest(stubPath = "specific-mappings")
    public void testDifferentMappings() {
     ....
}


Cheers & big thanks for the good work! Always happy for your feedback!
 Oliver
Reply all
Reply to author
Forward
0 new messages