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 就不会将空数组反序列化为空值