问题描述
我正在创建一个基于 Spring Boot 的微服务。此服务将调用外部服务。我想为该服务创建存根以进行集成测试。
我有以下配置。但是由于某种原因,我在运行我的测试类 Stub 时没有正确创建,因为我的测试失败了。
测试类
@SpringBoottest(webEnvironment = SpringBoottest.WebEnvironment.RANDOM_PORT,properties = {"server.context-path=/app","app.baseUrl=http://restapi-2.herokuapp.com"})
@AutoConfigurewiremock
@AutoConfiguremockmvc
class Restapi1ApplicationTests {
@Autowired
private ApiService apiService;
@Autowired
private RestTemplate restTemplate;
@Autowired
private ObjectMapper objectMapper;
@Autowired
private mockmvc mockmvc;
@Test
void contextLoads() {
}
@Test
void getMessage() throws Exception {
MockRestServiceServer mockRestServiceServer = wiremockRestServiceServer.with(this.restTemplate)
.baseUrl("http://restapi-2.herokuapp.com")
.stubs("classpath:/stubs/companyresponse.json").build();
CompanyDetail companyDetail = new CompanyDetail();
companyDetail.setCompanyName("Test");
mockmvc.perform(mockmvcRequestBuilders.get("/api/v1/messages"))
.andExpect(status().isOk())
//.andExpect(mockmvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON))
.andExpect(mockmvcResultMatchers.jsonPath("$.companyName").value("Test"));
//.andExpect(mockmvcResultMatchers.content().json(objectMapper.writeValueAsstring(companyDetail)));
}
}
@RestController
public class Api_1_Controller {
private final ApiService apiService;
public Api_1_Controller(ApiService apiService) {
this.apiService = apiService;
}
@GetMapping(path = "/api/v1/messages")
public CompanyDetail getMessage(){
CompanyDetail companyDetail = apiService.getMessageFromApi();
return companyDetail;
}
}
@Service
public class ApiService {
private RestTemplate restTemplate;
public ApiService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
public CompanyDetail getMessageFromApi(){
CompanyDetail companyDetail = null;
try{
companyDetail = restTemplate.getForEntity("http://restapi-2.herokuapp.com/companies",CompanyDetail.class).getBody();
}catch(Exception exception){
exception.printstacktrace();
throw exception;
}
return companyDetail;
}
}
@JsonInclude(value = JsonInclude.Include.NON_NULL)
public class CompanyDetail {
private String companyName;
//Getter and Setters
}
companyresponse.json 在下面的路径
test/resources/stubs
{
"request": {
"urlPath": "/companies","method": "GET"
},"response": {
"status": 200,"jsonBody": {"companyName" : "Test"},"headers": {
"Content-Type": "application/json"
}
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.heroku</groupId>
<artifactId>restapinew-1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>restapinew-1</name>
<description>restapi-1 project for Spring Boot</description>
<properties>
<java.version>11</java.version>
<spring-cloud.version>2020.0.2</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-contract-stub-runner</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<imageName>restapinew-1</imageName>
</configuration>
</plugin>
</plugins>
</build>
</project>
运行此测试用例时,响应正文为空
MockHttpServletResponse:
Status = 200
Error message = null
Headers = []
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
java.lang.AssertionError: No value at JSON path "$.companyName"
at org.springframework.test.util.JsonPathExpectationsHelper.evaluateJsonPath(JsonPathExpectationsHelper.java:304)
at org.springframework.test.util.JsonPathExpectationsHelper.assertValue(JsonPathExpectationsHelper.java:99)
解决方法
代替 JsonBody
使用 body
属性,将您的回复(json 回复)用双引号括起来可能会解决问题。