You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WebFluxTest上下文返回对象反序列化失败,生产环境正常

API控制器单元测试反序列化失败问题

问题场景

为API控制器编写单元测试时,遇到端点返回对象反序列化失败的问题。调试控制器函数时逻辑正常,但调用expectBody(UserDto.class)抛出错误。该功能在生产环境可正常运行,但测试上下文报错。

测试代码

String Id = "123";
UserTimestampDto userTimestampDto = new UserTimestampDto(LocalDateTime.now().toString());
TimestampsDto timestampsDto = new TimestampsDto(userTimestampDto, userTimestampDto);
UserDto userDto = new UserDto("123",timestampsDto);

webTestClient
        .get()
        .uri(uriBuilder -> uriBuilder
                .path(UserController.BASE_URL + "/" + Id)
                .build())
        .accept(MediaType.APPLICATION_JSON)
        .exchange()
        .expectStatus().isOk()
        .expectBody(UserDto.class)
        .value(userItem -> userItem, equalTo(userDto));

错误信息

org.springframework.core.codec.DecodingException: JSON解码错误:无法构造com.project.v1.model.timestamps.UserTimestampDto实例(尽管存在至少一个构造器):无法从对象值反序列化(无委托或基于属性的构造器);嵌套异常为com.fasterxml.jackson.databind.exc.MismatchedInputException:无法构造com.project.v1.model.timestamps.UserTimestampDto实例(尽管存在至少一个构造器):无法从对象值反序列化(无委托或基于属性的构造器)
at [Source: (org.springframework.core.io.buffer.DefaultDataBuffer$DefaultDataBufferInputStream); line: 1, column: 296](通过引用链:com.project.v1.model.customer.UserDto["internalTimestamps"]->com.project.v1.model.timestamps.TimestampsDto["createdDate"])

解决方案

核心原因

测试上下文的Jackson序列化配置与生产环境不一致,导致UserTimestampDto无法被正确反序列化。生产环境可能通过自动配置或自定义逻辑为DTO类添加了Jackson支持,但测试环境未同步生效。

具体修复步骤

  1. 为UserTimestampDto添加Jackson注解

    • 若类通过构造器初始化,添加@JsonCreator和@JsonProperty明确反序列化规则:
      public class UserTimestampDto {
          private String timestamp;
      
          @JsonCreator
          public UserTimestampDto(@JsonProperty("timestamp") String timestamp) {
              this.timestamp = timestamp;
          }
      
          @JsonProperty("timestamp")
          public String getTimestamp() {
              return timestamp;
          }
      }
      
    • 若使用Lombok,可通过注解自动生成必要的序列化支持:
      @Data
      @NoArgsConstructor
      @AllArgsConstructor
      public class UserTimestampDto {
          private String timestamp;
      }
      
  2. 同步测试上下文的Jackson配置

    • 确保测试类的@SpringBootTest或@WebMvcTest注解导入了生产环境的自定义Jackson配置类(如有),可通过@Import(YourJacksonConfig.class)实现。
  3. 验证返回JSON结构

    • 先打印返回的JSON内容,确认字段结构与DTO类匹配:
      webTestClient
              .get()
              .uri(...)
              .exchange()
              .expectStatus().isOk()
              .expectBody(String.class)
              .consumeWith(result -> System.out.println(result.getResponseBody()));
      
    • 检查JSON字段名与DTO类字段名的大小写、命名规则是否一致(Jackson默认遵循驼峰匹配)。

内容的提问来源于stack exchange,提问作者eyal tamsot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 08:55:37