首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用ExceptionHandler测试RestTemplate

用ExceptionHandler测试RestTemplate
EN

Stack Overflow用户
提问于 2021-12-20 12:46:38
回答 1查看 736关注 0票数 0

我有一种方法可以使外部API命中,并且编写了异常处理程序来处理错误并在发生错误时发送对客户端友好的响应。我需要测试来自外部API的非200 OK响应,例如坏请求、内部服务器错误,并断言应该调用异常处理程序方法来发送对客户端友好的消息。我能够成功地将外部API的响应模拟为坏请求,但它没有抛出HttpStatusCodeException,这是理想情况下为4xx状态代码抛出的,以及如何验证异常处理程序的方法调用

代码语言:javascript
复制
  private final RestTemplate restTemplate = Mockito.mock(RestTemplate.class);
  private final HttpHeaders httpHeaders = new HttpHeaders();
  private final NotificationServiceImpl notificationService = new NotificationServiceImpl(restTemplate, httpHeaders, NOTIFICATION_API_URL, PRIMARY_NOTIFIERS, CC_NOTIFIERS, LANG, APPLICATION_NAME);

  @Autowired
  private ExceptionTranslator exceptionTranslator;

  @Test
  void testErrorOnSendNotification() {
    Map<String, Instant> messages = Map.of("sample message", Instant.now());
    ResponseEntity<HttpStatusCodeException> responseEntity =
        new ResponseEntity<>(HttpStatus.BAD_REQUEST);

    when(restTemplate.exchange(
        ArgumentMatchers.anyString(),
        ArgumentMatchers.any(HttpMethod.class),
        ArgumentMatchers.any(),
        ArgumentMatchers.<Class<HttpStatusCodeException>>any()))
        .thenReturn(responseEntity);

//    assertThrows(HttpStatusCodeException.class, () -> notificationService.sendNotification(messages));
    verify(exceptionTranslator, times(1)).handleExceptions(any(), any());
  }

代码语言:javascript
复制
@ExceptionHandler(Exception.class)
  public ResponseEntity<Problem> handleExceptions(NativeWebRequest request, Exception error) {
    Problem problem =
        Problem.builder()
            .withStatus(Status.BAD_REQUEST)
            .withTitle(error.getMessage())
            .withDetail(ExceptionUtils.getRootCauseMessage(error))
            .build();
    return create(error, problem, request);
  }
EN

回答 1

Stack Overflow用户

发布于 2021-12-20 13:19:08

您正在模拟restTemplate响应。根本不调用实际的@ExceptionHandler。你绕过了那一层。

在您的示例中,为了验证ExceptionHandler,可以对您的service层进行模拟,但是实际的REST调用必须继续进行,并且必须触发一个真正的response,以便验证响应Status Code + message

Psuedo代码如下:

代码语言:javascript
复制
@Service
class Service{
 
    public void doSomeBusinessLogic() throws SomeException;
}
  
  
@RestController
class ControllerUsingService{

  @AutoWired
  private Service service;

  @POST
  public Response somePostMethidUsingService() throws SomeException{
    
      service.doSomeBusinessLogic(someString);
  }
}

代码语言:javascript
复制
  @Test
  void testErrorOnSendNotification() {

   when(service.doSomeBusinessLogic(anyString()))
  .thenThrow(SomeExceptionException.class);


    Response receivedResponse = restTemplate.post(request, headers, etc);
     
    //assert receivedResponse status code + message.
  }

希望这有意义,

为进一步澄清:

通过这样做:

代码语言:javascript
复制
ResponseEntity<HttpStatusCodeException> responseEntity =
        new ResponseEntity<>(HttpStatus.BAD_REQUEST);

    when(restTemplate.exchange(
        ArgumentMatchers.anyString(),
        ArgumentMatchers.any(HttpMethod.class),
        ArgumentMatchers.any(),
        ArgumentMatchers.<Class<HttpStatusCodeException>>any()))
        .thenReturn(responseEntity);

您正在绕过服务层,并且实际上声明,每当我向/API/xyz提出请求时,我都应该收到一个BAD_REQUEST。这意味着您拥有的任何异常处理都将被绕过。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70422030

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档