Uitzonderingen testen met Spring MockMvc

1. Overzicht

In dit korte artikel zullen we zien hoe uitzonderingen in onze controllers moeten worden gegooid en hoe deze uitzonderingen kunnen worden getest met Spring MockMvc.

2. Uitzonderingen toevoegen aan controllers

Laten we beginnen met leren hoe u een uitzondering start vanaf een controller.

We kunnen de services die we tonen vanaf een controller op dezelfde manier zien alsof het normale Java-functies zijn:

@GetMapping ("/ exception / throw") public void getException () gooit Exception {throw new Exception ("error"); } 

Laten we nu eens kijken wat er gebeurt als we deze dienst bellen. Ten eerste zullen we opmerken dat de responscode van de service 500 is, wat een interne serverfout betekent.

Ten tweede ontvangen we een reactie-instantie als deze:

{"timestamp": 1592074599854, "status": 500, "error": "Internal Server Error", "message": "Geen bericht beschikbaar", "trace": "java.lang.Exception op com.baeldung.controllers. ExceptionController.getException (ExceptionController.java:26) ... "}

Tot slot, wanneer we een uitzondering gooien van een RestControllerwordt de servicerespons automatisch toegewezen aan een 500-responscode en wordt de stacktracering van de uitzondering opgenomen in de hoofdtekst van het antwoord.

3. Uitzonderingen toewijzen aan HTTP-antwoordcodes

Nu gaan we leren hoe u onze uitzonderingen toewijst aan verschillende responscodes anders dan 500.

Om dit te bereiken, gaan we aangepaste uitzonderingen maken en de ResponseStatus annotatie die wordt geleverd door Spring. Laten we die aangepaste uitzonderingen maken:

@ResponseStatus (HttpStatus.BAD_REQUEST) openbare klasse BadArgumentsException breidt RuntimeException uit {openbare BadArgumentsException (String-bericht) {super (bericht); }}
@ResponseStatus (HttpStatus.INTERNAL_SERVER_ERROR) openbare klasse InternalException breidt RuntimeException uit {openbare InternalException (String-bericht) {super (bericht); }}
@ResponseStatus (HttpStatus.NOT_FOUND) openbare klasse ResourceNotFoundException breidt RuntimeException uit {openbare ResourceNotFoundException (String-bericht) {super (bericht); }}

De tweede en laatste stap is om een ​​eenvoudige service in onze controller te maken om deze uitzonderingen te voorkomen:

@GetMapping ("/ exception / {exception_id}") public void getSpecificException (@PathVariable ("exception_id") String pException) {if ("not_found" .equals (pException)) {throw new ResourceNotFoundException ("resource not found"); } else if ("bad_arguments" .equals (pException)) {throw new BadArgumentsException ("bad arguments"); } else {gooi nieuwe InternalException ("interne fout"); }}

Laten we nu eens kijken naar de verschillende reacties van de service voor de verschillende uitzonderingen die we in kaart hebben gebracht:

  • Voor niet gevondenontvangen we een responscode van 404
  • Gezien de waarde bad_argumentsontvangen we een responscode van 400
  • Voor elke andere waarde ontvangen we nog steeds 500 als antwoordcode

Afgezien van de responscodes ontvangen we een hoofdtekst met hetzelfde formaat als de antwoordtekst die we in de vorige sectie hebben ontvangen.

4. Testen van onze controllers

Eindelijk gaan we zien hoe we kunnen testen of onze controller de juiste uitzonderingen gooit.

De eerste stap is het maken van een testklasse en het maken van een instantie van MockMvc:

@Autowired privé MockMvc mvc; 

Laten we vervolgens de testcases maken voor elk van de waarden die onze service kan ontvangen:

@Test openbare leegte gegevenNotFound_whenGetSpecificException_thenNotFoundCode () genereert Uitzondering {String exceptionParam = "not_found"; mvc.perform (get ("/ exception / {exception_id}", exceptionParam) .contentType (MediaType.APPLICATION_JSON)) .andExpect (status (). isNotFound ()) .andExpect (resultaat -> assertTrue (result.getResolvedException () instantie van ResourceNotFoundException)) .andExpect (resultaat -> assertEquals ("resource niet gevonden", result.getResolvedException (). GetMessage ())); } @Test openbare leegte gegevenBadArguments_whenGetSpecificException_thenBadRequest () gooit uitzondering {String exceptionParam = "bad_arguments"; mvc.perform (get ("/ exception / {exception_id}", exceptionParam) .contentType (MediaType.APPLICATION_JSON)) .andExpect (status (). isBadRequest ()) .andExpect (resultaat -> assertTrue (result.getResolvedException () instantie van BadArgumentsException)) .andExpect (resultaat -> assertEquals ("slechte argumenten", resultaat.getResolvedException (). GetMessage ())); } @Test openbare leegte gegevenOther_whenGetSpecificException_thenInternalServerError () gooit uitzondering {String exceptionParam = "dummy"; mvc.perform (get ("/ exception / {exception_id}", exceptionParam) .contentType (MediaType.APPLICATION_JSON)) .andExpect (status (). isInternalServerError ()) .andExpect (resultaat -> assertTrue (result.getResolvedException () instantie van InternalException)) .andExpect (resultaat -> assertEquals ("interne fout", resultaat.getResolvedException (). GetMessage ())); }

Met deze tests controleren we of de responscode, het type uitzondering dat is opgetreden en de berichten van die uitzonderingen de verwachte berichten zijn voor elk van de waarden.

5. Conclusie

In deze tutorial hebben we geleerd hoe we in onze lente met uitzonderingen kunnen omgaan RestControllers en hoe te testen dat elke blootgestelde service de verwachte uitzonderingen genereert.

Zoals altijd is de volledige broncode van het artikel beschikbaar in GitHub.