HTTP响应和测试用例之间的Jackson反序列化不准确

问题描述

我有一个Spring Boot 2.3.2.RELEASE WebFlux应用程序。我有一些JPA实体是作为RESTful API响应的一部分返回的。

我使用@WebFluxTest进行的测试根据JSON模式检查HTTP响应和协定。我在这些测试中注入了Jackson的ObjecMapper和Spring WebTestClient,以根据相应/预期的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
  ...

我正在使用com.networknt:json-schema-validator:1.0.43库进行JSON模式实现。


其中一个测试用例的摘录:

@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()
          }
        }
  }

  // ...
}

使用Testcontainers在Docker容器中创建/播种测试数据。

解决方法

禁用DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT,以使Jackson不会将空数组反序列化为空值