如何用WebTestClient断言JSON仅包含指定字段?
如何确保接口返回的JSON仅包含指定字段?
针对你用WebTestClient的测试场景,有几种办法可以确保返回的JSON只有name、street、id这三个字段:
1. 使用严格模式的JSON匹配
直接用expectBody().json()方法,开启严格匹配模式(第二个参数设为true)。这种方式会对比预期JSON和实际返回的JSON,只要实际返回多了额外字段,测试就会失败。
示例代码:
webTestClient.get().uri(BASE_URL) .exchange() .expectStatus().isOk() .expectBody() .json(""" { "name": "test1", "street": "test1", "id": 1 } """, true); // strict=true,不允许存在预期外的字段
2. 提取JSON节点验证字段集合
通过consumeWith拿到返回的JSON内容,解析后直接检查字段的数量和具体名称,确保没有多余字段。
示例代码:
import com.jayway.jsonpath.JsonPath; import com.fasterxml.jackson.databind.JsonNode; import static org.assertj.core.api.Assertions.assertThat; webTestClient.get().uri(BASE_URL) .exchange() .expectStatus().isOk() .expectBody() .consumeWith(response -> { JsonNode jsonNode = JsonPath.read(response.getResponseBodyAsString(), "$"); Set<String> actualFields = jsonNode.fieldNames(); // 先检查字段总数是否为3 assertThat(actualFields.size()).isEqualTo(3); // 再检查是否正好包含指定的三个字段,没有额外的 assertThat(actualFields).containsExactlyInAnyOrder("name", "street", "id"); });
3. 通过DTO类反序列化验证
如果你的项目中有对应返回结构的DTO类,可以在DTO上配置Jackson遇到未知字段时抛出异常,然后用expectBody(DTO.class)来验证。这样返回的JSON只要有额外字段,反序列化就会失败,测试不通过。
首先定义DTO类(注意添加@JsonIgnoreProperties(ignoreUnknown = false)):
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.Data; @Data @JsonIgnoreProperties(ignoreUnknown = false) // 遇到未知字段时抛出异常 public class TargetDto { private String name; private String street; private Integer id; // 构造方法根据需要添加 public TargetDto(String name, String street, Integer id) { this.name = name; this.street = street; this.id = id; } }
然后编写测试代码:
webTestClient.get().uri(BASE_URL) .exchange() .expectStatus().isOk() .expectBody(TargetDto.class) .isEqualTo(new TargetDto("test1", "test1", 1));
以上三种方法可以根据你的实际场景选择:简单结构用严格JSON匹配最直接;需要灵活做字段校验选节点提取;已经有DTO类的项目用第三种更贴合业务代码。
内容的提问来源于stack exchange,提问作者ch1ll
相关产品推荐
相关产品推荐

