英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论