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