我有一个运行三个 Web 服务器的多模块项目。有一台服务器正在代理其他两台服务器的请求。
我想做集成测试:当整个应用程序运行时,我想运行 HTTP 请求并检查响应是否正确。我想运行与单元测试相同的测试,但使用不同的端口,因为代理也应该被测试。
? 如何告诉 Spring 我想在不启动应用程序的情况下运行测试?他们已经开始了。我只想发送请求并检查响应。
我有生成的单元测试http-request.adoc
和http-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;
}
}