Spring 引导 REST 控制器集成测试 returns 406 而不是 500
Spring Boot REST Controller Integration Test returns 406 instead of 500
我有一个控制器,其端点可生成压缩数据的字节流。下面代码中的 MyDtO
和 ZipService
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,但 MockMvc
的 HttpStatus
为 406 - 内容不可接受。我搞砸了测试,以便它可以接受并期望 any/all 数据,但它仍然每次都会遇到 406 错误。我知道它与异常的 RestError object 有关,因为如果我从控制器返回的 ResponseEntity
中取出它,则会返回预期的响应状态。对此的任何帮助表示赞赏。
从 @GetMapping(path = "/{id}/export", produces = "application/zip")
中删除产品
并将其更改为 @GetMapping(path = "/{id}/export")
因此在测试用例执行期间返回 406 错误
如果你删除它,你将得到你所抛出的确切错误。
但是请检查 zip 文件是否按预期下载。
我有一个控制器,其端点可生成压缩数据的字节流。下面代码中的 MyDtO
和 ZipService
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,但 MockMvc
的 HttpStatus
为 406 - 内容不可接受。我搞砸了测试,以便它可以接受并期望 any/all 数据,但它仍然每次都会遇到 406 错误。我知道它与异常的 RestError object 有关,因为如果我从控制器返回的 ResponseEntity
中取出它,则会返回预期的响应状态。对此的任何帮助表示赞赏。
从 @GetMapping(path = "/{id}/export", produces = "application/zip")
中删除产品
并将其更改为 @GetMapping(path = "/{id}/export")
因此在测试用例执行期间返回 406 错误 如果你删除它,你将得到你所抛出的确切错误。
但是请检查 zip 文件是否按预期下载。