java - Spring Cloud 合约测试无法正确解析 JSON
问题描述
我正在使用 Spring 云合同测试来尝试对 API 进行合同测试,但无法弄清楚是什么导致我的测试失败。
我正在使用这个 groovy 测试文件
package contracts.api.myClass;
import org.springframework.cloud.contract.spec.Contract
Contract.make {
request {
method 'GET'
url value(consumer(regex('path/myAPI/(\\w+)')), producer('/path/myAPI/id'))
headers {
contentType(applicationJson())
}
}
response {
status 200
headers {
contentType(applicationJson())
}
body("""
{
"requestId": "id",
"success": true,
"datalist": [
{
"id": 100,
"names": ["aaaa", "ffff"]
}
],
"failureInfo": {
"failureCode": 100,
"failureDesc": "failure"
}
}
""")
}
}
我尝试测试的 API 是使用来自以下 yaml 的 swagger code gen 2.0 生成的
'/configurator/myAPI/{requestId}':
get:
operationId: myAPI
parameters:
- $ref: '#/parameters/GCCX-Request-Context'
- $ref: '#/parameters/GCCX-TransactionId'
- $ref: '#/parameters/X-B3-TraceId'
- $ref: '#/parameters/Accept-Language'
- $ref: '#/parameters/requestId'
tags:
- Configurator
consumes: [ ]
responses:
'200':
description: Return the response once operation is preformed in BO.
headers:
Content-Language:
description: Describes the natural language(s) of the intended audience for the enclosed entity. Note that this might not be equivalent to all the languages used within the entity-body.
type: string
GCCX-TransactionId:
description: Id to trace the request for debugging purposes
type: string
X-B3-TraceId:
description: Sleuth trace id used to trace multiple requests
type: string
X-B3-SpanId:
description: Sleuth span id used for a single unit of work
type: string
schema:
$ref: '#/definitions/MyDataResponse'
'400':
$ref: "#/responses/BadRequest"
'401':
$ref: "#/responses/Unauthorized"
'403':
$ref: "#/responses/Forbidden"
'404':
$ref: "#/responses/NotFound"
'406':
$ref: "#/responses/NotAcceptable"
'415':
$ref: "#/responses/UnsupportedMediaType"
'429':
$ref: "#/responses/TooManyRequests"
'500':
$ref: "#/responses/InternalServerError"
'503':
$ref: "#/responses/ServiceUnavailable"
MyDataResponse:
type: object
required:
- requestId
- success
- datalist
- failureInfo
properties:
requestId:
type: string
success:
type: boolean
datalist:
type: array
items:
$ref: '#/definitions/DataEntry'
failureInfo:
$ref: "#/definitions/FailureInfo"
DataEntry:
type: object
required:
- names
- id
groovy 测试自动生成到以下 java 测试中:
@Test
public void validate_myAPI() throws Exception {
// given:
MockMvcRequestSpecification request = given()
.header("Content-Type", "application/json");
// when:
ResponseOptions response = given().spec(request)
.get("path/myAPI/id");
// then:
assertThat(response.statusCode()).isEqualTo(200);
assertThat(response.header("Content-Type")).matches("application/json.*");
// and:
DocumentContext parsedJson = JsonPath.parse(response.getBody().asString());
assertThatJson(parsedJson).field("['requestId']").isEqualTo("id");
assertThatJson(parsedJson).field("['success']").isEqualTo(true);
assertThatJson(parsedJson).array("['dataList']").contains("['id']").isEqualTo(100);
assertThatJson(parsedJson).array("['dataList']").array("['names']").arrayField().isEqualTo("aaaa").value();
assertThatJson(parsedJson).array("['dataList']").array("['names']").arrayField().isEqualTo("ffff").value();
assertThatJson(parsedJson).field("['failureInfo']").field("['failureCode']").isEqualTo(100);
assertThatJson(parsedJson).field("['failureInfo']").field("['failureDesc']").isEqualTo("failure");
当我运行此测试时,尝试从数据列表中获取 id 字段时失败,但出现以下异常。
java.lang.RuntimeException: com.jayway.jsonpath.PathNotFoundException: Missing property in path $['datalist']
在调试模式下运行,我可以验证 parsedJson 确实具有 dataList 映射和其中包含的元素,但在测试期间无法找到它们。是否有人对可能导致问题的原因或我可以采取哪些步骤来调试问题有任何想法?根据公司政策,我已将所有用例特定类型/api 更改为通用版本(即 myAPI、dataList 等),因此任何大小写问题或命名差异都可能是由于我对代码的转录而不是任何问题。我所有的组件和功能测试都顺利通过,所以我相信这只是我如何设置合同测试文件的问题
解决方案
推荐阅读
- javascript - 如何将 tinymce 编辑器配置为仅在表单提交时才将图像上传到服务器?
- c - setting input stream to return EOF repeatedly in loop
- matplotlib - 在水平 matplotlib 直方图上显示 x 轴值
- plot - 用 Gnuplot 表示散点图的灰色调色板
- gatsby - 如何使用 gatsby-cloudinary-plugin 进行过滤
- css - 根据背景设置颜色
- oracle - How can I convert an integer variable in PLSQL to pass to a boolean procedure parameter?
- laravel - 如何在不使用 foreach 命令的情况下获得 laravel join 方法?
- java - Scala - 如何将 LocalDateTime 转换为无 GMT 后缀格式的 ZonedDateTime?
- ruby-on-rails - Rails/Postgres:在数据库中保存 1000 种加密货币历史价格的策略