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

Spring测试配置异常:MockMvc standaloneSetup配置与Mock服务失效问题

解决standaloneSetup构建MockMvc时的Jackson配置与Mock注入问题

你遇到的两个问题本质都是standaloneSetup脱离了Spring容器上下文管理导致的,我来逐个给你梳理解决方案:

问题1:Jackson的non_null配置未生效

standaloneSetup是直接初始化控制器实例,不会自动加载Spring Boot中配置的Jackson属性。要让配置生效,有两种实用方式:

方式一:复用Spring容器中的HttpMessageConverter

既然你已经注入了WebApplicationContext,可以直接从上下文里获取已经配置好的MappingJackson2HttpMessageConverter,传给standaloneSetup即可:

@Before
public void setUp() {
    MockitoAnnotations.initMocks(this);
    // 从Spring上下文取出配置好的Jackson转换器
    MappingJackson2HttpMessageConverter configuredConverter = context.getBean(MappingJackson2HttpMessageConverter.class);
    mockMvc = standaloneSetup(controller)
            .setMessageConverters(configuredConverter) // 添加上这句
            .build();
}

方式二:手动配置ObjectMapper

如果不想依赖上下文,也可以手动创建ObjectMapper并设置non_null规则,再构建对应的消息转换器:

@Before
public void setUp() {
    MockitoAnnotations.initMocks(this);
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    MappingJackson2HttpMessageConverter customConverter = new MappingJackson2HttpMessageConverter(objectMapper);
    
    mockMvc = standaloneSetup(controller)
            .setMessageConverters(customConverter)
            .build();
}

问题2:@Mock的ModelService未正确注入

你用了@InjectMocks但没生效,大概率是因为@SpringBootTest会自动创建ModelController的容器实例,和你手动初始化的控制器产生了冲突。推荐改用更简洁的方案:放弃@InjectMocks和standaloneSetup,用@AutoConfigureMockMvc结合@MockBean实现,既能复用Spring配置,又能轻松替换Mock服务:

重构后的测试代码示例

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc // 自动配置MockMvc,复用整个Spring上下文
public class ModelControllerTests {
    private MediaType contentType = MediaType.APPLICATION_JSON_UTF8;
    @Autowired
    private MockMvc mockMvc;
    @MockBean // 自动把Mock的ModelService注入到容器中的ModelController里
    private ModelService service;

    @Test
    public void postModel_returnsModel() throws Exception {
        when(service.doSomething(any())).thenReturn(new Model("cde", null));
        mockMvc.perform(post("/model")
                        .content(json(new Model("abc", null)))
                        .contentType(contentType))
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(content().json("{\"notEmpty\":\"abc\"}", true));
    }

    // 直接用容器中配置好的ObjectMapper
    private String json(Object o) throws IOException {
        return context.getBean(ObjectMapper.class).writeValueAsString(o);
    }
}

这种方式下,你的spring.jackson.default-property-inclusion=non_null配置会自动生效,Mock的ModelService也能正确注入到控制器中,一次性解决两个问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:55:49