Spring Boot 不读取 Wire Mock Stub 响应体

问题描述

我正在创建一个基于 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 回复)用双引号括起来可能会解决问题。