首页 > 解决方案 > Spring Boot REST 控制器集成测试返回 406 而不是 500

问题描述

我有一个带有端点的控制器,该端点产生压缩数据的字节流。下面代码中的MyDtOZipService类是自定义类,它们充当 POJO,我想将其内容添加到 zip 和一个服务,它将获取 POJO 的字节并将它们写入 a ZipOutputStream,然后将通过包装的端点提供在ResponseEntity具有适当HttpStatus和标题的对象中。“快乐路径”运行良好,并且正在按预期生成 zip 文件。

@GetMapping(path = "/{id}/export", produces = "application/zip")
public ResponseEntity<byte[]> export(@ApiParam(required = true) @PathVariable(value = "id") String id) throws IOException {
    try {
        MyDTO myDTO = myService.getDTO(id);
        byte[] zippedData = zipService.createZip(myDTO.getBytes());
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\""name.zip\"");
        return new ResponseEntity<>(zipDTO.getData(), httpHeaders, HttpStatus.OK);
    } catch (ZipException e) {
        return new ResponseEntity(e.getRestError(), HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

当我想测试ZipException引发自定义的情况时,问题出在我的集成测试类中(如果压缩数据存在问题,可能会发生这种情况)。我们在组织中必须遵守的标准之一是每个自定义异常都需要扩展Exception并具有一个名为 RestError 的自定义对象,该对象具有表示自定义错误代码和消息的字符串变量。

@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class RestError {

    private String code;
    private String message;

    //Constructors

    //Getters and setters
}

该对象似乎导致集成测试出现问题

@Test
public void myIntegrationTest() throws Exception {
    MyDTO myDTO = new MyDTO();
    RestError restError = new RestError("Custom error code", "Custom error message")
    ZipException zipException = new ZipException(restError);
    given(myService.getDTO("id")).willReturn(myDTO);
    given(zipService.createZip(any(), any())).willThrow(zipException);

    mockMvc.perform(get("/{id}/export", "id").accept(MediaType.ALL)
            .andDo(print())
            .andExpect(status().is5xxServerError());
}

在这种情况下,我预计会HttpStatus达到 500,但MockMvc会达到HttpStatus406 - 内容不可接受。我已经搞砸了测试,以便它可以接受并期待任何/所有数据,但它仍然每次都会遇到 406 错误。我知道这与异常的 RestError 对象有关,因为如果我将其从ResponseEntity控制器返回的对象中取出,则会返回预期的响应状态。对此的任何帮助表示赞赏。

标签: javaspring-bootintegration-testing

解决方案


从中删除产品 @GetMapping(path = "/{id}/export", produces = "application/zip") 并将其更改为@GetMapping(path = "/{id}/export")

因此,在测试用例执行期间返回 406 错误如果删除它,您将得到确切的错误。

但是,请检查 zip 文件是否按预期下载。


推荐阅读