【问题标题】:Rest template doesn't return response entity after exception handler异常处理程序后,Rest 模板不返回响应实体
【发布时间】:2019-08-29 11:19:03
【问题描述】:

我有以下控制器方法

@PostMapping(consumes = "application/json",
             produces = "application/json")
public ResponseEntity<Board> createBoard(@Valid @RequestBody 
BoardRequestDTO boardRequestDTO) {
    Board board = new Board();
    board.setName(boardRequestDTO.getName());
    board.setCompanyId(Integer.valueOf(boardRequestDTO.getCompanyId()));
    board.setCode(boardRequestDTO.getCode());
    Board dbBoard = boardRepository.save(board);
    return new ResponseEntity<>(dbBoard, HttpStatus.CREATED);
} 

并有以下异常处理程序来处理验证错误

@ControllerAdvice
public class ExceptionHandlerConfig extends ResponseEntityExceptionHandler   {
    @Override
    protected ResponseEntity<Object>       
    handleMethodArgumentNotValid(MethodArgumentNotValidException ex, 
       HttpHeaders headers, HttpStatus status, WebRequest request) {
       ValidationErrorResponses validationErrorResponses = new 
       ValidationErrorResponses();
       for (FieldError fieldError : ex.getBindingResult().getFieldErrors())
       validationErrorResponses.addError(new ValidationError(fieldError.getField(),fieldError.getDefaultMessage()));

       ResponseEntity<Object> responseEntity = new ResponseEntity<Object> 
       (validationErrorResponses, HttpStatus.UNPROCESSABLE_ENTITY);
       return responseEntity;
    }

 }

当我通过 Postman 发送失败请求时,我得到了可预测的响应:

{
    "errors": [
         {
            "field": "companyId",
            "message": "Must be digit"
         }
    ]
}

但是当我尝试对此端点实施以下单元测试时,我得到 org.springframework.web.client.HttpClientErrorException$UnprocessableEntity: 422 null

boardDTO.setCompanyId("");
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "application/json");
headers.set("Accept", "application/json");
HttpEntity<ValidationErrorResponses> httpEntity = new HttpEntity(boardDTO, headers);

ResponseEntity<ValidationErrorResponses> responseEntity = 
restTemplate.postForEntity(url, httpEntity, ValidationErrorResponses.class);

ValidationErrorResponses responseBody = responseEntity.getBody();
assertEquals(422, responseEntity.getStatusCode());
assertEquals("companyId", responseBody.getErrors().get(0).getField());
assertEquals("Must be digit", responseBody.getErrors().get(0).getMessage()); 

我应该怎么做才能让我的测试正常工作?

【问题讨论】:

  • 请分享验证结果
  • 对不起,我不明白你的意思。我该怎么办?
  • 我的错,我理解错了问题。

标签: java spring-boot exception resttemplate


【解决方案1】:

为避免测试实现,我建议针对“已抛出”异常进行测试。异常的返回消息应该是异常单元测试的一部分:

@Test(expected = MethodArgumentNotValidException.class)
public void testMethodArgumentNotValidException() {
    boardDTO.setCompanyId("");
    HttpHeaders headers = new HttpHeaders();
    headers.set("Content-Type", "application/json");
    headers.set("Accept", "application/json");
    HttpEntity<ValidationErrorResponses> httpEntity = new HttpEntity(boardDTO, headers);

    ResponseEntity<ValidationErrorResponses> responseEntity = 
    restTemplate.postForEntity(url, httpEntity, ValidationErrorResponses.class);

}

否则问问自己是否可以通过用户接受测试来处理结果正文?

【讨论】:

  • 在您的代码中,我什至无法检查响应状态代码,因为响应实体为空,因为引发了异常并且没有返回结果。
  • 是的,我需要检查处理后的错误响应是否正确,而不是只抛出异常。
  • 异常的返回消息应该是异常单元测试的一部分
  • 你是对的,取决于附加的断言,所以我在上面的代码中改变了它。
【解决方案2】:

当状态 >= 400 且

try {
  restTemplate.postForEntity(url, httpEntity, ValidationErrorResponses.class);
  fail("should throw exception");
} catch (HttpClientErrorException e) {
  // Asserts go here using `e`
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-07-29
    • 2018-05-20
    • 2016-05-24
    • 1970-01-01
    • 2015-09-03
    • 2015-07-26
    • 2013-08-13
    • 1970-01-01
    相关资源
    最近更新 更多