如何使用Spring REST Docs进行集成测试?

时间:2016-09-28 08:08:39

标签: spring-boot integration-testing asciidoctor spring-restdocs

我有一个运行三个Web服务器的多模块项目。有一台服务器代理其他两台服务器的请求。

我想进行集成测试:当整个应用程序运行时,我想运行HTTP请求并检查响应是否正确。我想运行与我用于单元测试相同的测试但是使用不同的端口,因为代理也应该进行测试。

如何告诉Spring我想在不启动应用程序的情况下运行测试?他们已经开始了。我只是想发送请求并检查响应。

我有单元测试,可生成我在asciidoctor API文档中使用的http-request.adochttp-response.adoc个片段。

http-request.adoc示例:

GET /api?system=one&todo=123 HTTP/1.1
Accept: application/json
Host: localhost:8080

http-response.adoc示例:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 111
{"one":"123","two":abc,"three":"543","four":"789"}

我使用脚本参数:-Pintegration=true从单元测试模式切换到集成测试模式:

@Value("#{ systemProperties[integration] == 'true' ? true : false }")
private boolean integrationTest;

当我进行集成测试时,我不希望在请求中有Host: localhost:8080,而是在运行的主机和端口     代理应用程序(目前是localhost:8030)。怎么样     我实现了这个目标吗?

到目前为止我使用的代码
抽象测试类。模块的测试扩展了这个类:

@RunWith(SpringRunner.class)
public abstract class RestDocsTestGlobal {

 @Rule
 public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation("build/docs/generated-snippets");

 @Autowired
 private WebApplicationContext context;

 private MockMvc mockMvc;

 /*
  * Run unit- or integration-tests?
  * Add "script parameter": "-Pintegration=true" to enable integration tests.
  * Add "script parameter": "-Pintegration=false" to disable integration tests.
  * If the integration tests are enabled they replace the unit tests.
  */
 @Value("#{ systemProperties[integration] == 'true' ? true : false }")
 private boolean integrationTest;

 // "uri" gets the content of "integration" if we run integration tests
 String uri = "/api?";
 String folder = "unit-test";
 String integration = "http://localhost:8030/api?system=x&";
 String integrationTestFolder = "integration-test";

 @Before
 public void setUp() throws Exception {
  // Run unit- or integration-tests?
  if(integrationTest){
   uri = getIntegration();
   folder = getIntegrationTestFolder();
   System.out.println("Performing integration tests");
  }else{
   System.out.println("Not performing integration tests");
  }

  System.out.println("First part of the URI: "+uri);
  System.out.println("Test documentation folder: "+folder);

  this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
    .apply(MockMvcRestDocumentation.documentationConfiguration(this.restDocumentation))
    .build();
 }

 @Test
 public void smokeTest() throws Exception {
  this.mockMvc.perform(RestDocumentationRequestBuilders.get(getUri()).accept(MediaType.APPLICATION_JSON))
    .andExpect(status().isOk())
    .andDo(document(getFolder()+"/smoke-test"));
 }

 @Test
 public void statusTest() throws Exception {
  this.mockMvc.perform(RestDocumentationRequestBuilders.get(getUri()+"todo=123").accept(MediaType.APPLICATION_JSON))
    .andExpect(MockMvcResultMatchers.status().isOk())
    .andExpect(content().contentType("application/json;charset=UTF-8"))
    .andExpect(jsonPath("$.three").value("543"))
    .andDo(MockMvcRestDocumentation.document(getFolder()+"/status-test"));
 }

 public String getUri() {
  return uri;
 }

 public String getFolder() {
  return folder;
 }

 public String getIntegration() {
  return integration;
 }

 public String getIntegrationTestFolder() {
  return integrationTestFolder;
 }
}

代理模块知道发送请求的位置,我们覆盖每个模块的特定测试实现中的URL。例如:

@RunWith(SpringRunner.class)
@SpringBootTest
// Todo: Make sure that the configured port is used for integration testing.
// We want to have the correct port appear in the RestDocs documentation.
// I tried something like this but it didn't work:
// @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
// @ContextConfiguration(classes = AppRun.class)
public class RestDocsTest extends RestDocsTestGlobal {

 String integration = "http://localhost:8030/api?system=one&";

 @Override public String getIntegration() {
  return integration;
 }
}

0 个答案:

没有答案