+
+
Spring RestDocs can be
+used to generate documentation (e.g. in asciidoctor format) for an
+HTTP API with Spring MockMvc or RestEasy. At the same time as you
+generate documentation for your API, you can also generate WireMock
+stubs, by using Spring Cloud Contract WireMock. Just write your normal
+RestDocs test cases and use @AutoConfigureRestDocs to have stubs
+automatically in the restdocs output directory. For example:
+
+
+
+
@RunWith(SpringRunner.class)
+@SpringBootTest
+@AutoConfigureRestDocs(outputDir = "target/snippets")
+@AutoConfigureMockMvc
+public class ApplicationTests {
+
+ @Autowired
+ private MockMvc mockMvc;
+
+ @Test
+ public void contextLoads() throws Exception {
+ mockMvc.perform(get("/resource"))
+ .andExpect(content().string("Hello World"))
+ .andDo(document("resource"));
+ }
+}
+
+
+
+
From this test will be generated a WireMock stub at
+"target/snippets/stubs/resource.json". It matches all GET requests to
+the "/resource" path.
+
+
+
Without any additional configuration this will create a stub with a
+request matcher for the HTTP method and all headers except "host" and
+"content-length". To match the request more precisely, for example to
+match the body of a POST or PUT, we need to explicitly create a
+request matcher. This will do two things: 1) create a stub that only
+matches the way you specify, 2) assert that the request in the test
+case also matches the same conditions.
+
+
+
The main entry point for this is WireMockRestDocs.verify() which can
+be used as a substitute for the document() convenience method. For
+example:
+
+
+
+
@RunWith(SpringRunner.class)
+@SpringBootTest
+@AutoConfigureRestDocs(outputDir = "target/snippets")
+@AutoConfigureMockMvc
+public class ApplicationTests {
+
+ @Autowired
+ private MockMvc mockMvc;
+
+ @Test
+ public void contextLoads() throws Exception {
+ mockMvc.perform(post("/resource")
+ .content("{\"id\":\"123456\",\"message\":\"Hello World\"}"))
+ .andExpect(status.isOk())
+ .andDo(verify().jsonPath("$.id")
+ .stub("resource"));
+ }
+}
+
+
+
+
So this contract is saying: any valid POST with an "id" field will get
+back an the same response as in this test. You can chain together
+calls to .jsonPath() to add additional matchers. The
+JayWay documentation can help you
+to get up to speed with JSON Path if it is unfamiliar to you.
+
+
+
Instead of the jsonPath and contentType convenience methods, you
+can also use the WireMock APIs to verify the request matches the
+created stub. Example:
+
+
+
+
@Test
+public void contextLoads() throws Exception {
+ mockMvc.perform(post("/resource")
+ .content("{\"id\":\"123456\",\"message\":\"Hello World\"}"))
+ .andExpect(status.isOk())
+ .andDo(verify()
+ .wiremock(WireMock.post(
+ urlPathEquals("/resource"))
+ .withRequestBody(matchingJsonPath("$.id"))
+ .stub("post-resource"));
+}
+
+
+
+
The WireMock API is rich - you can match headers, query parameters,
+and request body by regex as well as by json path - so this can useful
+to create stubs with a wider range of parameters. The above example
+will generate a stub something like this:
+
+
+
post-resource.json
+
+
{
+ "request" : {
+ "url" : "/resource",
+ "method" : "POST",
+ "bodyPatterns" : [ {
+ "matchesJsonPath" : "$.id"
+ }]
+ },
+ "response" : {
+ "status" : 200,
+ "body" : "Hello World",
+ "headers" : {
+ "X-Application-Context" : "application:-1",
+ "Content-Type" : "text/plain"
+ }
+ }
+}
+
+
+
+
+
+|
+ Note
+ |
+
+You can use either the wiremock() method or the jsonPath()
+and contentType() methods to create request matchers, but not both.
+ |
+
+
+
+
+
On the consumer side, assuming the resource.json generated above is
+available on the classpath, you can create a stub using WireMock in a
+number of different ways, including as described above using
+@AutoConfigureWireMock(stubs="classpath:resource.json").
+
+