如何为返回PDF文件的Spring Boot测试用例设置内容类型

时间:2019-01-10 12:07:25

标签: spring spring-boot junit testcase spring-boot-test

我目前正在使用Spring boot test测试我的一项服务,该服务导出所有用户数据并在成功完成后生成CSV或PDF。在浏览器中下载文件。

下面是我在测试类中编写的代码

MvcResult result =   MockMvc.perform(post("/api/user-accounts/export").param("query","id=='123'")
    .contentType(MediaType.APPLICATION_JSON_VALUE)
    .accept(MediaType.APPLICATION_PDF_VALUE)
    .content(TestUtil.convertObjectToJsonBytes(userObjectDTO)))
    .andExpect(status().isOk())
    .andExpect(content().contentType(MediaType.APPLICATION_PDF_VALUE))
    .andReturn();
String content = result.getResponse().getContentAsString();  // verify the response string.

下面是我的资源类代码(调用到此位置)-

    @PostMapping("/user-accounts/export")
@Timed
public ResponseEntity<byte[]> exportAllUsers(@RequestParam Optional<String> query, @ApiParam Pageable pageable, 
@RequestBody UserObjectDTO userObjectDTO) {
HttpHeaders headers = new HttpHeaders();
.
.
.

 return new ResponseEntity<>(outputContents, headers, HttpStatus.OK);

 }

虽然我调试服务,然后在出口之前进行调试,但我得到的内容类型为“ application / pdf”,状态为200。我试图在测试用例中复制相同的内容类型。在执行过程中总以某种方式使其低于错误-

   java.lang.AssertionError: Status 
   Expected :200
   Actual   :406

我想知道,我应该如何检查我的响应(ResponseEntity)。同样,响应所需的内容类型应该是什么。

3 个答案:

答案 0 :(得分:1)

您在其他地方遇到了问题。似乎发生异常/错误,如application / problem + json内容类型所指出。这可能是在异常处理程序中设置的。由于您的客户只希望返回application / pdf 406。

您可以添加一个测试用例以读取错误详细信息,以了解确切的错误是什么。

类似

MvcResult result = MockMvc.perform(post("/api/user-accounts/export").param("query","id=='123'")
    .contentType(MediaType.APPLICATION_JSON_VALUE)
    .accept(MediaType.APPLICATION_PROBLEM_JSON_VALUE)
    .content(TestUtil.convertObjectToJsonBytes(userObjectDTO)))
    .andExpect(status().isOk())
    .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON_VALUE))
    .andReturn();
String content = result.getResponse().getContentAsString();  // This should show you what the error is and you can adjust your code accordingly. 

如果您预计会出现错误,则可以将接受类型更改为同时包含pdf和问题json类型。

注意-此行为取决于您拥有的spring web mvc版本。

最新的spring mvc版本考虑了在响应实体中设置的内容类型标头,并忽略了accept标头中提供的内容,并将响应解析为可能的格式。因此,您具有的同一测试将不会返回406代码,而是将返回具有应用程序json问题内容类型的内容。

答案 1 :(得分:0)

406表示您的客户正在请求服务器认为无法提供的contentType(可能是pdf)。

我猜测调试时代码能正常工作的原因是您的其余客户端没有添加ACCEPT标头,就像测试代码一样,它要求pdf。

要解决此问题,请添加到您的@PostMapping批注{{1}}参见https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/PostMapping.html#produces--

答案 2 :(得分:0)

我在@veeram的帮助下找到了答案,并了解到我对MappingJackson2HttpMessageConverter的配置不足。我覆盖了其默认支持的Mediatype,并解决了该问题。

默认支持-

implication/json
application*/json

已完成代码更改以解决此问题-

@Autowired
private MappingJackson2HttpMessageConverter jacksonMessageConverter;

List<MediaType> mediaTypes = new ArrayList<>();
mediaTypes.add(MediaType.ALL);
jacksonMessageConverter.setSupportedMediaTypes(mediaTypes);