简体   繁体   中英

Spring Boot, Global Exception Handling and Testing

Long story short. My service, throws EntityNotFound exceptions. By default Spring boot doesn't know what kind exception is that and how to treat it and simply displays a "500 Internal Server Error".

I had no choice but implementing my own exception handling mechanism.

There are several ways to resolve this issue with Spring boot. And I chose to use the @ControllerAdvice with @ExceptionHandler methods.

@ControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(EntityNotFoundException.class)
public ResponseEntity<ErrorDetails> handleNotFound(EntityNotFoundException exception, HttpServletRequest webRequest) {
    ErrorDetails errorDetails = new ErrorDetails(
            new Date(),
            HttpStatus.NOT_FOUND,
            exception,
            webRequest.getServletPath());

    return new ResponseEntity<>(errorDetails, HttpStatus.NOT_FOUND);
 }
}

So when the exception is being thrown, the new handler catches the exception and returns a nice json containing a message, like:

{
"timestamp": "2018-06-10T08:10:32.388+0000",
"status": 404,
"error": "Not Found",
"exception": "EntityNotFoundException",
"message": "Unknown employee name: test_name",
"path": "/assignments"
}

Implementing - not that hard. Hardest part is testing.

First of all, while testing spring doesn't seem to know of the new handler in test mode. How can i tell spring to be aware of a new implementation for handling such errors?

@Test
public void shouldShow404() throws Exception {
    mockMvc.perform(post("/assignments")
            .contentType(APPLICATION_JSON_UTF8_VALUE)
            .content(new ClassPathResource("rest/assign-desk.json").getInputStream().readAllBytes()))
            .andExpect(status().isNotFound());
}

As I see it, this test should pass but it doesn't.

Any thoughts are welcome. Thank You!

Found the answer.

For whom it may concern:

Settings apon class :

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class GlobalExceptionHandlerTest{
//
}

and the test:

@Test
public void catchesExceptionWhenEntityNotFoundWithSpecificResponse() throws Exception {

    mockMvc.perform(post("/assignments")
            .contentType(MediaType.APPLICATION_JSON_UTF8)
            .content(new ClassPathResource("rest/assign-desk.json").getInputStream().readAllBytes()))
            .andExpect(status().isNotFound())
            .andExpect(jsonPath("status").value(404))
            .andExpect(jsonPath("exception").value("EntityNotFoundException"))
            .andExpect(jsonPath("message").value("Unknown employee name: abc"));
}

Thank you all.

Possible duplicate of question or github issue . Don't know how you setup your test class. But if you have your test class anotated with WebMvcTest , all controllers and controller advices should be registered.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM