Spring 引导 REST 控制器集成测试 returns 406 而不是 500

Spring Boot REST Controller Integration Test returns 406 instead of 500

我有一个控制器,其端点可生成压缩数据的字节流。下面代码中的 MyDtOZipService classes 是自定义的 classes,它们用作 POJO,我想将其内容添加到 zip 和一个服务POJO 的字节并将它们写入 ZipOutputStream,然后通过包含在 ResponseEntity object 中的端点使用适当的 HttpStatus 和 headers. “happy path”工作正常,正在按预期生成 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);
    }
}

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

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

    private String code;
    private String message;

    //Constructors

    //Getters and setters
}

这 object 似乎会导致集成测试出现问题

@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,但 MockMvcHttpStatus 为 406 - 内容不可接受。我搞砸了测试,以便它可以接受并期望 any/all 数据,但它仍然每次都会遇到 406 错误。我知道它与异常的 RestError object 有关,因为如果我从控制器返回的 ResponseEntity 中取出它,则会返回预期的响应状态。对此的任何帮助表示赞赏。

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

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

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