首页 > 解决方案 > How to document @ControllerAdvice handled exception using Spring REST Docs

问题描述

I have @ControllerAdvice annotated class, which is handling BadRequestException extends RuntimeException exception.

Now suppose that I have endpoint:

@PostMapping(value = "/createAccount")
public ResponseEntity<CreateAccountResponse> createAccount(@RequestBody @Valid CreateAccountRequest createAccountRequest) {...}

In case of unwanted scenario, endpoint throws BadRequestException (with HTTP Status 400) which constructs error JSON object as following:

{ 
  "errorCode": 123,
  "errorMessage: "Failure reason"
}

Is there any way to document case like this using Spring REST Docs ?

This is example of my approach:

@Test
public void createAccountFailExample() {

       RestDocumentationResultHandler docs = document("create-acc-fail-example",
       responseFields(
                        fieldWithPath("errorCode").type("Integer").description("Error code"),
                        fieldWithPath("errorMessage").type("String").description("Error message")
                )
        );

        org.assertj.core.api.Assertions.assertThatThrownBy(() -> this.mockMvc.perform(RestDocumentationRequestBuilders.post("/createAccount")
                        .contextPath("/account")
                        .contentType(TestUtil.APPLICATION_JSON_UTF8)
                        .content(TestUtil.convertObjectToJsonBytes(new CreateAccountRequest("nameTest", "surnameTest"))))
                        .andExpect(status().isBadRequest())
                        .andDo(docs)).hasCause(new BadRequestException(ServiceError.SOME_FAIL_REASON));
}

In this case test passes, but no documentation (.adoc) files are created.

When I try something like this:

ResultActions resultActions = this.mockMvc.perform(RestDocumentationRequestBuilders.post("/createAccount")
                .contextPath("/account")
                .contentType(TestUtil.APPLICATION_JSON_UTF8)
                .content(TestUtil.convertObjectToJsonBytes(new CreateAccountRequest("testName", "testSurname"))))
                .andExpect(status().isBadRequest())
                .andDo(docs);

test fails because NestedServletException was thrown caused by BadRequestException, and again there is no documentation created.

标签: javaspringtestingdocumentationspring-restdocs

解决方案


I managed to solve the problem following this answer. When exception handler is defined for MockMvc, my second approach works as expected.


推荐阅读