MockMvc不处理AccessDeniedException。

huangapple go评论73阅读模式
英文:

MockMvc does not handle AccessDeniedException

问题

我有一个类似这样运行的POST调用

assertThrows("Access Denied for non Blappity Roles",
    () -> mvc.perform(post(url)
           .content(requestStr)
           .accept(ContentType.APPLICATION_JSON.toString())
           .with(csrf())
           .contentType(MediaType.APPLICATION_JSON))
           .andExpect(__ -> assertThat(__.getResolvedException(),
               CoreMatchers.instanceOf(AccessDeniedException.class))),
    Matchers.instanceOf(AccessDeniedException.class))

我确实以以下方式定义了异常处理程序

@ExceptionHandler(AccessDeniedException.class)
public void accessDeniedException(HttpServletRequest request, HttpServletResponse response, Exception e) throws Exception {
    e.printStackTrace(System.err);
    log.error("Access Denied Exception {}", e.getClass(), e);
    throw e;

无论如何,测试都失败了,mockmvc.perform没有捕获AccessDeniedException,测试失败并显示AccessDeniedException逃脱了我的匹配器。我猜测的是,我抛出的异常被某个其他过滤器吞噬了。有没有办法让MockMvc捕获异常?

英文:

I have a post call that runs something like this

 assertThrows("Access Denied for non Blappity Roles",
                 () -> mvc.perform(post(url)
                                    .content(requestStr)
                                    .accept(ContentType.APPLICATION_JSON.toString())
                                    .with(csrf())
                                    .contentType(MediaType.APPLICATION_JSON))
                               .andExpect(__ -> assertThat(__.getResolvedException(),                                             CoreMatchers.instanceOf(AccessDeniedException.class))),
                 Matchers.instanceOf(AccessDeniedException.class))

I do have an Exception Handler defined this way

   @ExceptionHandler(AccessDeniedException.class)
 public void accessDeniedException(HttpServletRequest request, HttpServletResponse response, Exception e) throws Exception {
     e.printStackTrace(System.err);
     log.error("Access Denied Exception {}", e.getClass(), e);
     throw e;

No matter what, the test fails, and mockmvc perform does not capture the AccessDeniedException, and the test fails with.. guess what, AccessDeniedException that escapes my Matcher.
What I am guessing is, the exception I am throwing is being gobbled by another filter somewhere. Is there anyway I can get MockMvc to get the exception?

答案1

得分: 1

因为你从它的 @ExceptionHandler 重新抛出了 AccessDeniedException ,它被视为未解决的异常,但 MockMvc 只会捕获已解决的异常。所以 AccessDeniedException 从未被解决,因此 getResolvedException() 为 null。

通常情况下,你不需要从 @ExceptionHandler 中重新抛出异常,只需通过配置HTTP响应中应该回复的HTTP状态码或响应体来处理它。

此外,假设你真的解决了 AccessDeniedException ,则不需要在 mockMvc.perform() 中使用 assertThrows() 包装它。只需使用 mockMvc.perform().andExpect(xxx) 进行断言。

英文:

Because you re-throw AccessDeniedException from its @ExceptionHandler ,it is considered as unresolved exception but MockMvc will only capture the resolved exception. So AccessDeniedException is never resolved and hence getResolvedException() is null.

Normally you do not need to rethrow the exception from @ExceptionHandler , just handle it by configuring what HTTP status code or response body should be replied in the HTTP response.

Also suppose you really resolve AccessDeniedException , you do not need to wrap the mockMvc.perform() in the assertThrows(). Just use mockMvc.perform().andExpect(xxx) for assertion.

huangapple
  • 本文由 发表于 2023年3月1日 14:06:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/75600093.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定