使用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();