我调查了一下为什么这样做会如此。重申一下,让我的自定义ObjectMapper在我的测试中工作的过程(假定MockMvc是作为独立的创建的)如下:
- 创建一个
WebConfig
扩展类WebMvcConfigurerAdapter
。 - 在
WebConfig
该类中,创建一个@Bean
返回的新值MappingJackson2HttpMessageConverter
。这MappingJackson2HttpMessageConverter
已应用了所需的更改(在我的情况下,将其传递给Jackson2ObjectMapperBuilder
,且PropertyNamingStrategy
设置为CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES
。) - 同样在
WebConfig
该类中,@Override
configureMessageConverters()
并将MappingJackson2HttpMessageConverter
from(2)添加到消息转换器列表中。 - 在测试文件中,添加
@ContextConfiguration(classes = { WebConfig.class })注释以通知您的测试@Bean
。 - 使用
@Autowired
注入和访问的@Bean
(2)中所定义。 - 在的设置中
MockMvc
,使用.setMessageConverters()
方法并将其传递给注入MappingJackson2HttpMessageConverter
。现在,测试将使用(2)中设置的配置。
测试文件:
package com.myproject.controller;import org.junit.Before;import org.junit.Test;import org.junit.runner.RunWith;import org.mockito.InjectMocks;import org.mockito.Mock;import org.mockito.MockitoAnnotations;import org.springframework.http.MediaType;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import org.springframework.test.context.web.AnnotationConfigWebContextLoader;import org.springframework.test.context.web.WebAppConfiguration;import org.springframework.test.web.servlet.MockMvc;import org.springframework.test.web.servlet.MvcResult;import org.springframework.test.web.servlet.setup.MockMvcBuilders;import static org.mockito.Mockito.when;import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;// Along with other application imports...@RunWith(SpringJUnit4ClassRunner.class)@WebAppConfiguration@ContextConfiguration(classes = {WebConfig.class})public class MyControllerTest { @Autowired private MappingJackson2HttpMessageConverter jackson2HttpMessageConverter; @Mock private MyManager myManager; @InjectMocks private MyController myController; private MockMvc mockMvc; @Before public void setup() { MockitoAnnotations.initMocks(this); this.mockMvc = MockMvcBuilders .standaloneSetup(this.myController) .setMessageConverters(this.jackson2HttpMessageConverter) // important! .build(); } @Test public void testMyControllerWithNameParam() throws Exception { MyEntity expected = new MyEntity(); String name = "expected"; String title = "expected title"; // Set up MyEntity with data. expected.setId(1); // Random ID. expected.setEntityName(name); expected.setEntityTitle(title) // When the MyManager instance is asked for the MyEntity with name parameter, // return expected. when(this.myManager.read(name)).thenReturn(expected); // Assert the proper results. MvcResult result = mockMvc.perform( get("/v1/endpoint") .param("name", name)) .andExpect(status().isOk()) .andExpect((content().contentType("application/json;charset=UTF-8"))) .andExpect(jsonPath("$.entity_name", is(name)))) .andExpect(jsonPath("$.entity_title", is(title))) .andReturn(); System.out.println(result.getResponse().getContentAsString()); }}和配置文件:
package com.myproject.config;import com.fasterxml.jackson.databind.PropertyNamingStrategy;import org.springframework.context.annotation.*;import org.springframework.http.converter.HttpMessageConverter;import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;import org.springframework.web.servlet.config.annotation.EnableWebMvc;import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;import java.util.List;@Configuration@EnableWebMvcpublic class WebConfig extends WebMvcConfigurerAdapter { @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { converters.add(jackson2HttpMessageConverter()); } @Bean public MappingJackson2HttpMessageConverter jackson2HttpMessageConverter() { MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); Jackson2ObjectMapperBuilder builder = this.jacksonBuilder(); converter.setObjectMapper(builder.build()); return converter; } public Jackson2ObjectMapperBuilder jacksonBuilder() { Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); builder.propertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES); return builder; }}将我生成的WAR文件部署到XAMPP中的Tomcat
7表示正确使用了命名策略。我认为这样做是可行的,因为在独立安装中,除非另有说明,否则始终使用默认的消息转换器集。可以
setMessageConverters()在StandAloneMockMvcBuilder.java(版本4.1.6,
orgspringframeworktestwebservletsetupStandaloneMockMvcBuilder.java)中的函数注释中看到:
public StandaloneMockMvcBuilder setMessageConverters(HttpMessageConverter<?>...messageConverters) { this.messageConverters = Arrays.asList(messageConverters); return this; }因此,如果在构建MockMvc的过程中未明确告知MockMvc有关消息转换器的更改,它将不会使用这些更改。



