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
相关产品推荐
相关产品推荐

