2016-09-15 99 views
0

使用Spring HATEOAS创建服务,并与mockmvc测试它(也使用Spring restdocs生成文档),我们发现以下后。春HATEOAS和mockMVC,忽略消耗= MediaType.APPLICATION_JSON_UTF8_VALUE

我们RestController看起来像:

@RestController 
@RequestMapping("/v1/my") 
@ExposesResourceFor(My.class) 
@EnableHypermediaSupport(type = EnableHypermediaSupport.HypermediaType.HAL) 
public class MyController { 

    @Autowired 
    private MyRepository myRepository; 

    @Autowired 
    private MyResourceAssembler myResourceAssembler; 

    @RequestMapping(path = "", method = POST, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE) 
    public HttpEntity<Resource<MyResource>> addMy(
     @RequestBody MyResource newMyResource) { 

    if (myRepository.existsByMyId(newMyResource.getMyId())) { 
     return new ResponseEntity<>(HttpStatus.CONFLICT); 
    } 

    val newMy = new My(
      null, // generates id 
      newMy.getMyId() 
    ); 

    val myResource = myResourceAssembler.toResource(myRepository.save(newMy)); 
    val resource = new Resource<>(myResource); 

    return new ResponseEntity<>(resource, HttpStatus.CREATED); 
    } 
} 

为了验证这一点,我们已经创建了以下测试:

@Test 
public void addMy() throws Exception { 
    this.mockMvc.perform(post("/v1/my") 
      .content("{ \"myId\": 9911 }") 
      .contentType(MediaType.APPLICATION_JSON_UTF8) 
      .accept(MediaTypes.HAL_JSON)) 
      .andExpect(status().isCreated()) 
      .andExpect(MockMvcResultMatchers.jsonPath("$.myId").value(9911)) 
      .andDo(this.document.document(selfLinkSnippet, responseFieldsSnippet)); 
} 

单元测试结果,我们得到的是:

java.lang.AssertionError: Status 
Expected :201 
Actual :415 

状态代码415是不受支持的媒体类型。

如果我们修改了单元测试的说:

.contentType(MediaTypes.HAL_JSON) 

单元测试返回成功。这是奇怪的,因为我们表示只使用application/json。现在 的问题是,所生成的文档,错误地指出POST请求应使用内容类型application/HAL + JSON:

curl 'http://my-service/v1/my' -i -X POST -H 'Content-Type: application/hal+json' -H 'Accept: application/hal+json' -d '{ "myId": 9911 }' 

如果你尝试,你会得到另一个415 如果我们将Content-Type:更改为application/json,然后它可以工作。

如果我们说该方法要消耗两者HAL + JSON和JSON:

@RequestMapping(path = "", method = POST, consumes = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_UTF8_VALUE}) 

然后,单元测试成功时的contentType(MediaTypes.HAL_JSON)被设置,但是当的contentType(MediaType.APPLICATION_JSON_UTF8)是失败组。

然而,现在两个服务接受应用/ JSON和应用/ HAL + JSON,使得所述文档的至少工作。

有谁知道这是为什么?

回答

0

我发现了另外一个计算器问题:Spring MVC controller ignores "consumes" property

而且该解决方案对我有工作过。我将@EnableWebMvc添加到测试配置类中。

@EnableWebMvc 
@Configuration 
@Import({CommonTestConfiguration.class}) 
@EnableHypermediaSupport(type = EnableHypermediaSupport.HypermediaType.HAL) 
public class MyControllerTestConfiguration { 

    @Bean 
    public MyRepository myRepository() { 

     return new InMemoryMyRepository(); 
    } 

    @Bean 
    public MyController myController() { 
     return new MyController(); 
    } 

    @Bean 
    public MyResourceAssembler myResourceAssembler() { 
     return new myResourceAssembler(); 
    } 
}