-
-
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").
-
-