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

Spring Boot中带非空构造函数的自定义反序列化器单元测试问题

问题描述

我有一个Spring Boot MVC应用,为MyObject类使用了自定义反序列化器。该自定义反序列化器类包含一个带参数的构造函数:

@JsonDeserialize(using = MyObjectDeserializer.class)
class MyObject {
. . .
}

@Component
class MyObjectDeserializer extends JsonDeserializer<MyObject> {

  private AnotherObject anotherObject;

  @Autowired
  public MyObjectDeserializer(AnotherObject anotherObject) {
    this.anotherObject = anotherObject;
  }
 ...
}

运行应用时一切正常,这是Spring自动装配机制在起作用:相关组件会创建ObjectMapper Bean,以及AnotherObject和MyObjectDeserializer的Bean。但在单元测试中该机制失效:

@RunWith(SpringRunner.class)
public void MyObjectDeserTest {


    @Autowired
    private ObjectMapper objectMapper;
}

测试中objectMapper为null。请问如何在单元测试中正确初始化ObjectMapper,使反序列化器能正确加载依赖?或者是否有更合理的方式为反序列化器注入对象?

解决方案

方案一:修正单元测试配置

你的测试类缺少Spring Boot的测试启动注解,导致Spring上下文未正确初始化,所以ObjectMapper无法被注入。修改测试类如下:

@RunWith(SpringRunner.class)
@SpringBootTest // 添加上该注解,启动Spring Boot上下文
public class MyObjectDeserTest { // 注意这里是class而非void

    @Autowired
    private ObjectMapper objectMapper;

    // 测试方法示例
    @Test
    public void testDeserialization() throws JsonProcessingException {
        String json = "{...}";
        MyObject result = objectMapper.readValue(json, MyObject.class);
        // 编写断言逻辑
    }
}

如果只想加载必要Bean而非完整应用上下文,可以使用@WebMvcTest或自定义配置类配合@ContextConfiguration:

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {MyObjectDeserializer.class, AnotherObject.class, JacksonAutoConfiguration.class})
public class MyObjectDeserTest {

    @Autowired
    private ObjectMapper objectMapper;

    // 测试方法
}

方案二:改进反序列化器的注入方式

方式1:自定义Jackson配置注册反序列化器

移除MyObject类上的@JsonDeserialize(using = MyObjectDeserializer.class)注解,通过配置类手动注册反序列化器:

@Configuration
public class JacksonConfig {

    @Autowired
    private MyObjectDeserializer myObjectDeserializer;

    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
        module.addDeserializer(MyObject.class, myObjectDeserializer);
        objectMapper.registerModule(module);
        return objectMapper;
    }
}

这种方式下,单元测试只要加载JacksonConfig及相关依赖Bean,就能获取配置正确的ObjectMapper。

方式2:使用@JsonComponent自动注册

用@JsonComponent标记反序列化器,Spring Boot会自动识别并将其注册到ObjectMapper中,无需手动配置:

@JsonComponent // 替换原有的@Component和@JsonDeserialize的using属性
class MyObjectDeserializer extends JsonDeserializer<MyObject> {

  private AnotherObject anotherObject;

  @Autowired
  public MyObjectDeserializer(AnotherObject anotherObject) {
    this.anotherObject = anotherObject;
  }
 ...
}

此时MyObject类上的@JsonDeserialize(using = ...)可直接移除,Spring会自动关联反序列化器,单元测试中启动Spring上下文即可正常注入ObjectMapper。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 04:54:16