使用@SpringBootTest测试时如何覆盖默认的标准ObjectMapper?
问题根因
你当前使用MockMvcBuilders.standaloneSetup()手动构造MockMvc实例,这种独立测试模式不会自动加载Spring上下文中的WebMvcConfigurer配置、自定义消息转换器等Web层组件,只会使用Spring默认的序列化/反序列化配置,因此你自定义的ObjectMapper不会被Spring Web层逻辑识别。
解决方案
以下两种方案可按需选择:
方案1:保留独立测试模式,手动注入自定义消息转换器
适合想要轻量测试、手动控制控制器实例的场景,只需修改MockMvc构建逻辑,把自定义转换器传入即可:
- 先在测试类中注入自定义的Jackson消息转换器
- 构建MockMvc时调用
setMessageConverters方法绑定转换器
@Autowired private MappingJackson2HttpMessageConverter customJacksonConverter; @Before public void setUp() { TarifControllerJson controller = new CustomContoller(bean); this.mockMvc = MockMvcBuilders.standaloneSetup(controller) .setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver()) // 加入自定义的消息转换器 .setMessageConverters(customJacksonConverter) .build(); }
对应的InnerWebConfig可以保留你实现WebMvcConfigurer的配置,也可以直接注册自定义消息转换器Bean:
@Configuration public class InnerWebConfig { @Bean public MappingJackson2HttpMessageConverter customJacksonConverter() { MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); converter.setObjectMapper(new CustomObjectMapper()); return converter; } @Bean("testObjectMapper") public ObjectMapper objectMapper() { return new CustomObjectMapper(); } }
方案2:改用上下文加载模式构建MockMvc
如果需要完全复用Spring上下文的Web层配置,无需手动初始化控制器,切换为webAppContextSetup模式即可:
@RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @ContextConfiguration(classes = InnerWebConfig.class) public class TarifControllerJsonTest { private MockMvc mockMvc; @Autowired private WebApplicationContext context; @MockBean private CustomBean bean; @Autowired @Qualifier("testObjectMapper") private ObjectMapper objectMapper; @Before public void setUp() { this.mockMvc = MockMvcBuilders.webAppContextSetup(context).build(); } // 测试方法保持不变 }
这种模式下你配置的WebMvcConfigurer会自动生效,无需额外手动配置消息转换器。
补充优化建议
如果只是需要替换全局序列化/反序列化使用的ObjectMapper,不需要单独配置消息转换器,直接注册一个@Primary的ObjectMapper Bean即可,Spring默认的Jackson消息转换器会自动拾取这个优先级最高的ObjectMapper:
@Configuration public class InnerWebConfig { @Bean @Primary public ObjectMapper objectMapper() { return new CustomObjectMapper(); } }
内容的提问来源于stack exchange,提问作者Aleksey Gareev
相关产品推荐
相关产品推荐

