1

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

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

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


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

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;
 }
}
4

0 回答 0