使用MockServletContext进行unit testing

我已经使用Gradle设置了spring boot应用程序。 现在我明白了@EnableAutoConnfiguration根据类路径中的依赖关系来配置应用程序。 我很高兴避免所有的管道,但事情开始发生,我希望不会。

这是我的依赖项:

dependencies { compile('org.springframework.boot:spring-boot-starter-web:1.2.3.RELEASE') compile 'org.springframework.hateoas:spring-hateoas:0.17.0.RELEASE' compile 'org.springframework.plugin:spring-plugin-core:1.2.0.RELEASE' compile 'org.springframework.boot:spring-boot-starter-data-jpa' compile 'com.google.guava:guava:18.0' compile 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310' compile 'commons-beanutils:commons-beanutils:1.9.2' runtime 'org.hsqldb:hsqldb:2.3.2' testCompile 'org.springframework.boot:spring-boot-starter-test' testCompile 'com.jayway.jsonpath:json-path:2.0.0' } 

我的应用类:

 @ComponentScan("org.home.project") @SpringBootApplication //@EnableHypermediaSupport(type = EnableHypermediaSupport.HypermediaType.HAL) public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } 

UserController的一个片段:

 @RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE) public HttpEntity create(@Valid @RequestBody UserCreateRequest ucr, BindingResult bindingResult) { if (bindingResult.hasErrors()) throw new InvalidRequestException("Bad Request", bindingResult); Long userId = userService.create(ucr); ResourceSupport resource = new ResourceSupport(); resource.add(linkTo(UserEndpoint.class).withSelfRel()); resource.add(linkTo(methodOn(UserEndpoint.class).update(userId, null, null)).withRel(VIEW_USER)); resource.add(linkTo(methodOn(UserEndpoint.class).delete(userId)).withRel(DELETE_USER)); return new ResponseEntity(resource, HttpStatus.CREATED); } 

UserController.java有两个注释:

 @RestController @RequestMapping(value = "/users", produces = MediaType.APPLICATION_JSON_VALUE) 

首先 – 注意注释掉@EnableHyperdiaSupport注释 – 尽管生成了媒体类型并在请求中设置了媒体类型,但ResourceSupport实例中的链接仍然被序列化为hal + json格式。 当依赖项中引入‘org.springframework.plugin:spring-plugin-core:1.2.0.RELEASE’时会自动发生这种情况。 如何明确配置它?

另一个问题是unit testing。

通过:

 @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = MockServletContext.class) @WebAppConfiguration public class UserControllerTest { ...ommited for brevity... @InjectMocks private UserController testObject; @Before public void setUp() throws Exception { initMocks(this); mockMvc = standaloneSetup(testObject).build(); } @Test public void testUserCreatedLinks() throws Exception { mockMvc.perform(post("/users").contentType(MediaType.APPLICATION_JSON).content(data)) .andExpect(status().isCreated()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)).andExpect(jsonPath("$.links.[*].rel", hasItem("self"))); } ...ommited fro brevity... } 

post请求在测试中返回标准JSON响应 – 而不是HAL + JSON。 有没有办法重新配置这个,以便unit testing@RestController与MockServletContext将产生HAL + JSON或回到问题1 – 如何明确配置响应格式,以便jackson序列化器不会产生hal + json?

您正在使用Spring MVC Test的standaloneSetup运行测试,该standaloneSetup使用最少的配置来启动和运行控制器。 该配置与运行整个应用程序时将使用的配置不同。

如果要使用相同的配置,可以使用webAppContextSetup

 @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration public class SomeTests { @Autowired private WebApplicationContext context; private MockMvc mockMvc; @Before public void setUp() { this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build(); } } 

或者,您可以在独立设置中复制Spring HATEOAS的配置。 请注意,这会导致测试配置偏离应用程序配置的风险。 你可以像这样创建MockMvc实例:

 TypeConstrainedMappingJackson2HttpMessageConverter messageConverter = new TypeConstrainedMappingJackson2HttpMessageConverter(ResourceSupport.class); messageConverter.setSupportedMediaTypes(Arrays.asList(MediaTypes.HAL_JSON)); ObjectMapper objectMapper = messageConverter.getObjectMapper(); objectMapper.registerModule(new Jackson2HalModule()); objectMapper.setHandlerInstantiator( new Jackson2HalModule.HalHandlerInstantiator(new DefaultRelProvider(), null)); MockMvc mockMvc = MockMvcBuilders.standaloneSetup(testObject) .setMessageConverters(messageConverter).build();