Obtention et vérification des données de réponse avec la garantie REST

Haut REST

Je viens d'annoncer le nouveau cours Learn Spring , axé sur les principes de base de Spring 5 et Spring Boot 2:

>> VOIR LE COURS

1. Vue d'ensemble

Dans ce didacticiel, nous allons discuter de la façon de tester les services REST à l'aide de la garantie REST, en mettant l'accent sur la capture et la validation des données de réponse à partir de nos API REST .

2. Configuration pour la classe de test

Dans les didacticiels précédents, nous avons exploré la garantie REST en général et nous avons montré comment manipuler les en-têtes de demande, les cookies et les paramètres.

Sur la base de cette configuration existante, nous avons ajouté un contrôleur REST simple, AppController , qui appelle en interne un service, AppService . Nous utiliserons ces classes dans nos exemples de test.

Pour créer notre classe de test, nous devons faire un peu plus de configuration. Puisque nous avons spring-boot-starter-test dans notre classpath, nous pouvons facilement tirer parti des utilitaires de test Spring.

Commençons par créer le squelette de notre classe AppControllerIntegrationTest :

@RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) public class AppControllerIntegrationTest { @LocalServerPort private int port; private String uri; @PostConstruct public void init() { uri = "//localhost:" + port; } @MockBean AppService appService; //test cases }

Dans ce test JUnit, nous avons annoté notre classe avec quelques annotations spécifiques à Spring qui font tourner l'application localement dans un port disponible aléatoire. Dans @PostConstruct , nous avons capturé l'URI complet sur lequel nous allons effectuer des appels REST.

Nous avons également utilisé @MockBean sur AppService , car nous devons simuler les appels de méthode sur cette classe.

3. Validation de la réponse JSON

JSON est le format le plus couramment utilisé dans les API REST pour échanger des données. Les réponses peuvent être constituées d'un seul objet JSON ou d'un tableau d'objets JSON. Nous examinerons les deux dans cette section.

3.1. Objet JSON unique

Disons que nous devons tester le point de terminaison / movie / {id} , qui renvoie un objet Movie JSON si l' id est trouvé.

Nous allons simuler les appels AppService pour renvoyer des données simulées à l'aide du framework Mockito:

@Test public void givenMovieId_whenMakingGetRequestToMovieEndpoint_thenReturnMovie() { Movie testMovie = new Movie(1, "movie1", "summary1"); when(appService.findMovie(1)).thenReturn(testMovie); get(uri + "/movie/" + testMovie.getId()).then() .assertThat() .statusCode(HttpStatus.OK.value()) .body("id", equalTo(testMovie.getId())) .body("name", equalTo(testMovie.getName())) .body("synopsis", notNullValue()); }

Ci-dessus, nous nous sommes d'abord moqués de l' appel appService.findMovie (1) pour renvoyer un objet. Ensuite, nous avons construit notre URL REST dans la méthode get () fournie par REST-assuré pour faire des requêtes GET. Enfin, nous avons fait quatre affirmations.

Tout d'abord, nous avons vérifié le code d'état de la réponse, puis les éléments du corps . Nous utilisons Hamcrest pour affirmer la valeur attendue.

Notez également que si la réponse JSON est imbriquée, nous pouvons tester une clé imbriquée en utilisant l' opérateur point comme «key1.key2.key3» .

3.2. Extraction de la réponse JSON après validation

Dans certains cas, nous pouvons avoir besoin d'extraire la réponse après validation, pour y effectuer des opérations supplémentaires.

Nous pouvons extraire la réponse JSON à une classe, en utilisant la méthode extract () :

Movie result = get(uri + "/movie/" + testMovie.getId()).then() .assertThat() .statusCode(HttpStatus.OK.value()) .extract() .as(Movie.class); assertThat(result).isEqualTo(testMovie);

Dans cet exemple, nous avons demandé à REST-Assuré d'extraire la réponse JSON à un objet Movie , puis de l'affirmer sur l'objet extrait.

Nous pouvons également extraire la réponse entière à une chaîne, en utilisant l' API extract (). AsString () :

String responseString = get(uri + "/movie/" + testMovie.getId()).then() .assertThat() .statusCode(HttpStatus.OK.value()) .extract() .asString(); assertThat(responseString).isNotEmpty();

Enfin, nous pouvons également extraire un champ particulier du JSON de réponse .

Examinons un test pour une API POST qui attend un corps Movie JSON et retournera le même s'il est inséré avec succès:

@Test public void givenMovie_whenMakingPostRequestToMovieEndpoint_thenCorrect() { Map request = new HashMap(); request.put("id", "11"); request.put("name", "movie1"); request.put("synopsis", "summary1"); int movieId = given().contentType("application/json") .body(request) .when() .post(uri + "/movie") .then() .assertThat() .statusCode(HttpStatus.CREATED.value()) .extract() .path("id"); assertThat(movieId).isEqualTo(11); }

Ci-dessus, nous avons d'abord créé l'objet de requête dont nous avons besoin pour POST. Nous avons ensuite extrait le champ id de la réponse JSON renvoyée à l'aide de la méthode path () .

3.3. Tableau JSON

Nous pouvons également vérifier la réponse s'il s'agit d'un tableau JSON:

@Test public void whenCallingMoviesEndpoint_thenReturnAllMovies() { Set movieSet = new HashSet(); movieSet.add(new Movie(1, "movie1", "summary1")); movieSet.add(new Movie(2, "movie2", "summary2")); when(appService.getAll()).thenReturn(movieSet); get(uri + "/movies").then() .statusCode(HttpStatus.OK.value()) .assertThat() .body("size()", is(2)); }

Nous nous sommes à nouveau moqué de appService.getAll () avec des données et avons fait une demande à notre point de terminaison. Nous avons ensuite affirmé le statusCode et la taille de notre tableau de réponses.

Cela peut encore être fait via l'extraction:

Movie[] movies = get(uri + "/movies").then() .statusCode(200) .extract() .as(Movie[].class); assertThat(movies.length).isEqualTo(2);

4. Validation des en-têtes et des cookies

Nous pouvons vérifier un en-tête ou un cookie de la réponse à l'aide de méthodes portant le même nom:

@Test public void whenCallingWelcomeEndpoint_thenCorrect() { get(uri + "/welcome").then() .assertThat() .header("sessionId", notNullValue()) .cookie("token", notNullValue()); }

Nous pouvons également extraire les en-têtes et les cookies individuellement:

Response response = get(uri + "/welcome"); String headerName = response.getHeader("sessionId"); String cookieValue = response.getCookie("token"); assertThat(headerName).isNotBlank(); assertThat(cookieValue).isNotBlank();

5. Validation des fichiers

Si notre API REST renvoie un fichier, nous pouvons utiliser la méthode asByteArray () pour extraire la réponse:

File file = new ClassPathResource("test.txt").getFile(); long fileSize = file.length(); when(appService.getFile(1)).thenReturn(file); byte[] result = get(uri + "/download/1").asByteArray(); assertThat(result.length).isEqualTo(fileSize);

Ici, nous avons d'abord simulé appService.getFile (1) pour renvoyer un fichier texte présent dans notre chemin src / test / resources . Nous avons ensuite appelé notre point de terminaison et extrait la réponse dans un octet [] , que nous avons ensuite affirmé avoir la valeur attendue.

6. Conclusion

Dans ce didacticiel, nous avons examiné différentes façons de capturer et de valider les réponses de nos API REST à l'aide de REST-Assuré.

Comme d'habitude, le code de cet article est disponible à l'adresse over sur Github.

REST bas

Je viens d'annoncer le nouveau cours Learn Spring , axé sur les principes de base de Spring 5 et Spring Boot 2:

>> VOIR LE COURS