使用RestDocs生成存根

优质
小牛编辑
132浏览
2023-12-01

Spring RestDocs可用于为具有Spring MockMvc或RestEasy的HTTP API生成文档(例如,asciidoctor格式)。在生成API文档的同时,还可以使用Spring Cloud Contract WireMock生成WireMock存根。只需编写正常的RestDocs测试用例,并使用@AutoConfigureRestDocs在restdocs输出目录中自动存储存根。例如:

@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"));
	}
}

从此测试将在“target / snippets / stubs / resource.json”上生成一个WireMock存根。它将所有GET请求与“/ resource”路径相匹配。

没有任何其他配置,这将创建一个存根与HTTP方法的请求匹配器和除“主机”和“内容长度”之外的所有头。为了更准确地匹配请求,例如要匹配POST或PUT的正文,我们需要明确创建一个请求匹配器。这将做两件事情:1)创建一个只匹配您指定的方式的存根,2)断言测试用例中的请求也匹配相同的条件。

主要的入口点是WireMockRestDocs.verify(),可以替代document()便利方法。例如:

@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"));
	}
}

所以这个合同是说:任何有效的POST与“id”字段将得到与本测试相同的响应。您可以将来电链接到.jsonPath()以添加其他匹配器。如果 您不熟悉JayWay文档,可以帮助您加快JSON路径的速度。

您也可以使用WireMock API来验证请求是否与创建的存根匹配,而不是使用jsonPathcontentType方法。例:

@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"));
}

WireMock API是丰富的 - 您可以通过正则表达式以及json路径来匹配头文件,查询参数和请求正文,因此这可以用于创建具有更广泛参数的存根。上面的例子会生成一个这样的stub:

后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"
  }
  }
}
注意您可以使用wiremock()方法或jsonPath()contentType()方法创建请求匹配器,但不能同时使用两者。

在消费方面,假设上面生成的resource.json可以在类路径中使用,您可以使用WireMock以多种不同的方式创建一个存根,其中包括上述使用@AutoConfigureWireMock(stubs="classpath:resource.json")的描述。