HTTP 响应和测试用例之间的杰克逊(反)序列化不准确
Jackson (de)serialization not accurate between HTTP responses and test cases
我有一个 Spring Boot 2.3.2.RELEASE
WebFlux 应用程序。我有一些 JPA 实体作为 RESTful API 响应的一部分返回。
我的测试(使用 @WebFluxTest
)检查 HTTP 响应和合同——针对 JSON 模式。我在这些测试中注入了 Jackson 的 ObjecMapper
和 Spring WebTestClient
以根据 corresponding/expected JSON 模式检查 HTTP 响应。
问题是:如果我在应用程序为 运行 时使用任何 HTTP 客户端,则没有元素的集合(在 Java 端)被序列化为空 JSON数组——这就是我所期望的,不管理论上是对还是错;但在测试用例中,相同的空集合正在使用 null
值进行序列化。
所以我想知道 为什么会有所不同?我希望在任何时候都有相同的 JSON 字符串。
我知道我没有使用不同的 ObjectMapper
设置 — 或者这就是我的想法。我没有那种类型的自定义 Spring bean,所以我使用的是 Spring Boot 默认注入的任何东西,所以它必须与 运行 应用程序以及当 运行 测试时。 Jackson 的唯一自定义是在 application.yml
:
中的应用程序级别完成的
spring:
...
jackson:
property-naming-strategy: LOWER_CAMEL_CASE
serialization:
write-date-timestamps-as-nanoseconds: false
write-dates-as-timestamps: true
...
I'm using the com.networknt:json-schema-validator:1.0.43
library for the JSON schema implementation.
其中一个测试用例的摘录:
@WebFluxTest(controllers = [ExamController::class])
internal class ExamControllerTest {
@Autowired
private lateinit var webClient: WebTestClient
@Autowired
private lateinit var mapper: ObjectMapper
@Test
@Disabled
fun getById_ValidateResponseAgainstSchema() {
// IMPORTANT: If you update anything here, make the corresponding changes also to getById_WhenRecordExists
webClient.get()
.uri("/exams/10001030")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk
.expectBody()
.consumeWith { result ->
val schemaFactory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V201909)
this::class.java.getResourceAsStream("/json-schemas/exam/exam-details.json").use {
Assertions.assertThat(schemaFactory.getSchema(it).validate(mapper.readTree(result.responseBody))).isEmpty()
}
}
}
// ...
}
测试数据 created/seeded 在一个 Docker 容器中,使用 Testcontainers。
禁用 DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT
,这样 Jackson 就不会将空数组反序列化为空值
我有一个 Spring Boot 2.3.2.RELEASE
WebFlux 应用程序。我有一些 JPA 实体作为 RESTful API 响应的一部分返回。
我的测试(使用 @WebFluxTest
)检查 HTTP 响应和合同——针对 JSON 模式。我在这些测试中注入了 Jackson 的 ObjecMapper
和 Spring WebTestClient
以根据 corresponding/expected JSON 模式检查 HTTP 响应。
问题是:如果我在应用程序为 运行 时使用任何 HTTP 客户端,则没有元素的集合(在 Java 端)被序列化为空 JSON数组——这就是我所期望的,不管理论上是对还是错;但在测试用例中,相同的空集合正在使用 null
值进行序列化。
所以我想知道 为什么会有所不同?我希望在任何时候都有相同的 JSON 字符串。
我知道我没有使用不同的 ObjectMapper
设置 — 或者这就是我的想法。我没有那种类型的自定义 Spring bean,所以我使用的是 Spring Boot 默认注入的任何东西,所以它必须与 运行 应用程序以及当 运行 测试时。 Jackson 的唯一自定义是在 application.yml
:
spring:
...
jackson:
property-naming-strategy: LOWER_CAMEL_CASE
serialization:
write-date-timestamps-as-nanoseconds: false
write-dates-as-timestamps: true
...
I'm using the
com.networknt:json-schema-validator:1.0.43
library for the JSON schema implementation.
其中一个测试用例的摘录:
@WebFluxTest(controllers = [ExamController::class])
internal class ExamControllerTest {
@Autowired
private lateinit var webClient: WebTestClient
@Autowired
private lateinit var mapper: ObjectMapper
@Test
@Disabled
fun getById_ValidateResponseAgainstSchema() {
// IMPORTANT: If you update anything here, make the corresponding changes also to getById_WhenRecordExists
webClient.get()
.uri("/exams/10001030")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk
.expectBody()
.consumeWith { result ->
val schemaFactory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V201909)
this::class.java.getResourceAsStream("/json-schemas/exam/exam-details.json").use {
Assertions.assertThat(schemaFactory.getSchema(it).validate(mapper.readTree(result.responseBody))).isEmpty()
}
}
}
// ...
}
测试数据 created/seeded 在一个 Docker 容器中,使用 Testcontainers。
禁用 DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT
,这样 Jackson 就不会将空数组反序列化为空值