W poprzednim tygodniu wrzucałem zbiór bibliotek przydatnych w projektach Java, a dziś prezentuję kawałek kodu, który również, od długiego czasu, zalegał w czeluściach moich notatek. Pokazuje on, jak, w prosty sposób, przetestować (z wykorzystaniem frameworku Spock) funkcjonalność @ExceptionHandler
-ów dostępną w Springu.
Kod produkcyjny
Na początek przygotujmy użycie @ExceptionHandler
-a:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
package pl.programistanaswoim.test.spring.exceptions.handling; import static org.springframework.http.HttpStatus.NOT_FOUND; import com.google.common.collect.ImmutableMap; import javax.persistence.EntityNotFoundException; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; @RestControllerAdvice @RequiredArgsConstructor class ApplicationExceptionsHandler { @ExceptionHandler(EntityNotFoundException.class) @ResponseStatus(NOT_FOUND) public Object handleEntityNotFoundException(EntityNotFoundException ex) { return ImmutableMap.of("message", ex.getMessage()); } } |
Pomocniczy endpoint
Zanim przejdziemy do właściwego testu, stwórzmy pomocniczy endpoint, który będzie rzucał dowolny zadany mu wyjątek:
|
package pl.programistanaswoim.test.spring.exceptions.handling import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController @RestController @RequestMapping("/exception") class ExceptionThrowingController { @GetMapping void throwException(@RequestParam String type, @RequestParam(required = false) String message) { throw this.class.classLoader.loadClass(type).newInstance(message) } } |
Test
Na koniec przejdźmy do właściwego testu, który wykorzysta nasz pomocniczy endpoint do rzucenia wyjątku javax.persistence.EntityNotFoundException
i sprawdzenia, czy nasz @ExceptionHandler
przechwyci go, zwracając status 404 z odpowiednim komunikatem:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
|
package pl.programistanaswoim.test.spring.exceptions.handling import static groovy.json.JsonOutput.toJson import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status import javax.persistence.EntityNotFoundException import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest import org.springframework.test.web.servlet.MockMvc import spock.lang.Specification @WebMvcTest(ExceptionThrowingController) class ApplicationExceptionsHandlerTest extends Specification { @Autowired protected MockMvc mvc def "should return 404 when EntityNotFoundException was thrown"() { given: final exceptionType = EntityNotFoundException final exceptionMsg = 'I did not find what you want' when: final request = mvc.perform( get("/exception") .param('type', exceptionType.name) .param('message', exceptionMsg) ) then: request .andExpect(status().isNotFound()) .andExpect(content().json(toJson([message: exceptionMsg]))) } } |
Prawda, że proste? 🙂
Picture Credits
Dodaj komentarz