Spring's MockMVC Responses Don't Match Browser Response

旧巷老猫 提交于 2019-12-08 04:57:14

问题


For some reason, my Spring controller is returning different responses if I access it via a browser or via my MockMVC test class. Could someone help me spot why?

First the controller method:

@RequestMapping(value = APPLICATIONS_ROOT, method = GET)
  public HttpEntity<ApplicationsListResource> listApplications(@PageableDefault(page = DEFAULT_START,
      size = DEFAULT_HITS_PER_PAGE) Pageable pageable) {
    Page<Application> applications = applicationRepository.findAll(pageable);
    ApplicationsListResource applicationListResource = new ApplicationsListResource(applications, pageable);
    return new ResponseEntity<ApplicationsListResource>(applicationListResource, HttpStatus.OK);
  }

Obviously there's a few unknown classes in there. ApplicationListResource extends ResourceSupport and contains a list of ApplicationResource called applications. This ApplicationResource also extends ResourceSupport.

When I access the code via the browser, I'll get something along the lines of:

{
  "_links": {
    "self": {
      "href": "http://localhost:10000/applications{?page,size,sort}",
      "templated": true
    }
  },
  "_embedded": {
    "applications": [{
      "displayname": "One",
      "description": "My Test Application!",
      "locations": ["http://foo.com"],
      "_links": {
        "self": { "href": "http://localhost:10000/applications/one" }
      }
    }, {
      ...
    }]
  },
  "page": {
    "size": 20,
    "totalElements": 7,
    "totalPages": 1,
    "number": 0
  }
}

Looks HATEOAS compliant to me. But when I go via a MockMVC request...

getMockMvc().perform(get(APPLICATIONS_ROOT)).andExpect(status().isOk()).andExpect(content().contentType(MediaTypes.HAL_JSON)).andExpect(jsonPath("$._embedded.applcations", hasSize(5))).andReturn();

The responses have no HATEOAS compliant elements in them so my tests fail on the jsonPath check:

{
  "page" : 0,
  "size" : 10,
  "sort" : null,
  "total" : 5,
  "applications" : [ {
    "name" : "one",
    "version" : "1.0",
    ...

I've tried changing the ContentType on the GET request for the MockMVC method but it makes no difference. In the browser, I'm not setting any specific content type, headers etc.

I know the MockMVC class makes it HTTP requests with certain differences from the usual RestTemplate so perhaps it's something like this? Can anyone see anything obvious I am missing?

I will add additional code if needs be but it would have made the question even more long winded than it is currently.


回答1:


Spring HATEOAS adds additional configuration for rendering hal properly, check this for details: http://docs.spring.io/spring-hateoas/docs/0.19.0.RELEASE/reference/html/#configuration.

In a nutshell it adds proper MixIns added by Jackson2HalModule and HalHandlerInstantiator to the ObjectMapper. It's all configured in HypermediaSupportBeanDefinitionRegistrar.java (https://github.com/spring-projects/spring-hateoas/blob/master/src/main/java/org/springframework/hateoas/config/HypermediaSupportBeanDefinitionRegistrar.java)

If you're using standalone mockMvc configuration you have to configure the ObjectMapper manually to mimic spring's behaviour. I ran into same problem and ended up adding following configuration to my tests:

mockMvc = MockMvcBuilders.standaloneSetup(controller)
        .setMessageConverters(
                new MappingJackson2HttpMessageConverter(configureObjectMapper()))
        .build();

and

private ObjectMapper configureObjectMapper() {
    return Jackson2ObjectMapperBuilder.json()
        .modules(new Jackson2HalModule())
        .handlerInstantiator(new Jackson2HalModule.HalHandlerInstantiator(
            new DelegatingRelProvider(
                OrderAwarePluginRegistry.create(Arrays.asList(
                    new EvoInflectorRelProvider(),
                    new AnnotationRelProvider()))),
            null))
        .build();
}


来源:https://stackoverflow.com/questions/33127031/springs-mockmvc-responses-dont-match-browser-response

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!