[英]How to write integration tests for spring boot rest API using wiremock, rest assured, Junit5
我有一个基本的spring boot项目rest api,我想为我的rest api编写集成测试。 技术栈:wiremock,放心,Junit5。 如何进一步进行。
首先在pom文件中添加相关依赖
<!-- Testing --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <version>2.5.</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-contract-stub-runner</artifactId> <version>2021.0.2</version> <scope>test</scope> </dependency> <dependency> <groupId>com.github.tomakehurst</groupId> <artifactId>wiremock-jre8</artifactId> <version>2.31.0</version> <scope>test</scope> </dependency> <dependency> <groupId>com.epages</groupId> <artifactId>restdocs-api-spec-restassured</artifactId> <version>0.16.1</version> </dependency>
创建基础集成测试类
import io.restassured.RestAssured;
import io.restassured.config.JsonConfig;
import io.restassured.config.LogConfig;
import io.restassured.config.RestAssuredConfig;
import io.restassured.path.json.config.JsonPathConfig;
import org.junit.jupiter.api.BeforeEach;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock;
import org.springframework.test.context.TestPropertySource;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
//To start the stub server on random port, use a value of 0
@AutoConfigureWireMock(port = 0, stubs ="classpath:/stubs")
@TestPropertySource(properties = {
"external-service.host=http://localhost:${wiremock.server.port}"
})
@Import(BaseIntegrationTestClass.TestConfig.class)
public class BaseIntegrationTestClass {
@LocalServerPort
int serverPort = 0;
@BeforeEach
void setUpRestAssured() {
RestAssured.port = serverPort;
RestAssured.config = RestAssuredConfig.newConfig()
.jsonConfig(JsonConfig.jsonConfig().numberReturnType(JsonPathConfig.NumberReturnType.DOUBLE))
.logConfig(LogConfig.logConfig().enableLoggingOfRequestAndResponseIfValidationFails());
}
//override beans of your choice
@TestConfiguration
public static class TestConfig {
@Bean
@Primary
public WebServiceTemplate mockWebServiceTemplate() {
WebServiceTemplate template = mock(WebServiceTemplate.class);
when(template.getDefaultUri()).thenReturn("/hello");
return template;
}
}
}
import io.restassured.RestAssured;
import io.restassured.response.Response;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpStatus;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
public class RestControllerIT extends BaseIntegrationTestClass{
@Test
public void testStatusCodePositive() {
Response response = RestAssured.given().
when().
get("/");
assertThat(response.statusCode(), equalTo(HttpStatus.OK.value()));
assertThat(response.body().asString(), equalTo("Hello World"));
}
}
import service.ExternalApiService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class YourController {
@Autowired
private ExternalApiService externalApiService;
@GetMapping("/")
public String checkEligibility() {
return this.ExternalApiService.go();
}
}
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class ExternalApiService {
private final RestTemplate restTemplate;
@Value("${external-service.host}")
private String base;
ExternalApiService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
public String go() {
return this.restTemplate.getForEntity(this.base + "/activities", String.class)
.getBody();
}
}
external-service.host="https://example.org"
{
"request": {
"urlPathPattern": "/activities",
"method": "GET"
},
"response": {
"status": 200,
"body": "Hello World"
}
}
// for urls with path params /car/garage/{garageNum}/location/{locationNum}
{
"request": {
"urlPathPattern": "/car/garage.*/location.*",
"method": "GET"
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"jsonBody":
{
"msg": "hello world",
}
}
}
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.7</version>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>pre-integration-test</id>
<phase>pre-integration-test</phase>
<goals>
<goal>prepare-agent-integration</goal>
</goals>
<configuration>
<propertyName>failsafeArgLine</propertyName>
</configuration>
</execution>
<execution>
<id>post-integration-test</id>
<phase>post-integration-test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/site/jacoco-it</outputDirectory>
</configuration>
</execution>
<execution>
<id>merge-unit-and-integration</id>
<phase>post-integration-test</phase>
<goals>
<goal>merge</goal>
</goals>
<configuration>
<fileSets>
<fileSet>
<directory>${project.build.directory}</directory>
<includes>
<include>*.exec</include>
</includes>
</fileSet>
</fileSets>
<destFile>${project.build.directory}/jacoco-merged.exec</destFile>
</configuration>
</execution>
<execution>
<id>create-merged-report</id>
<phase>post-integration-test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<dataFile>${project.build.directory}/jacoco-merged.exec</dataFile>
<outputDirectory>${project.reporting.outputDirectory}/jacoco-merged</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.