Tests d’intégration au printemps

Test d'intégration au printemps

1. Vue d'ensemble

Les tests d'intégration jouent un rôle important dans le cycle de développement d'applications en vérifiant le comportement de bout en bout du système.

Dans cet article, nous verrons comment exploiter l'infrastructure de test Spring MVC afin d'écrire et d'exécuter des tests d'intégration testant des contrôleurs sans démarrer explicitement un conteneur Servlet.

2. Préparation

Les dépendances Maven suivantes sont nécessaires pour exécuter les tests d'intégration, comme décrit dans cet article. Tout d'abord les dernières dépendances deJUnit etSpring test:


    junit
    junit
    4.12
    test


    org.springframework
    spring-test
    4.3.2.RELEASE
    test

Pour une affirmation efficace des résultats, nous allons également utiliserHamcrest etJSON path:


    org.hamcrest
    hamcrest-library
    1.3
    test


    com.jayway.jsonpath
    json-path
    2.2.0
    test

3. Configuration du test Spring MVC

Voyons maintenant comment configurer et exécuter les tests compatibles avec Spring.

3.1. Activer le printemps dans les tests

Tout d'abord, tout test activé par Spring s'exécutera à l'aide de@RunWith(SpringJUnit4ClassRunner.class); le coureur est essentiellement le point d'entrée pour commencer à utiliser le framework Spring Test.

Nous avons également besoin des annotations@ContextConfiguration pour charger la configuration de contexte etbootstrap the context that the test will use.

Regardons:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { ApplicationConfig.class })
@WebAppConfiguration
public class GreetControllerIntegrationTest {
    ....
}

Remarquez comment, dans@ContextConfiguration,, nous avons fourni la classe de configurationApplicationConfig.class qui charge la configuration dont nous avons besoin pour ce test particulier.

Nous avons utilisé ici une classe de configuration Java pour spécifier la configuration du contexte; De même, nous pouvons utiliser la configuration basée sur XML:

@ContextConfiguration(locations={""})

Enfin - le test est également annoté avec@WebAppConfiguration – which will load the web application context.

Par défaut, il recherche l'application Web racine au chemin par défautsrc/main/webapp; l'emplacement peut être remplacé en passant l'argument valeur comme suit:

@WebAppConfiguration(value = "")

3.2. L'objetWebApplicationContext

WebApplicationContext (wac) fournit la configuration de l'application Web. Il charge tous les beans d'application et les contrôleurs dans le contexte.

Nous allons maintenant pouvoir câbler le contexte de l'application Web directement dans le test:

@Autowired
private WebApplicationContext wac;

3.3. Mocking Web Context Beans

MockMvc prend en charge les tests Spring MVC. Il encapsule tous les beans d'application Web et les met à la disposition des tests.

Voyons comment l'utiliser:

private MockMvc mockMvc;
@Before
public void setup() throws Exception {
    this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}

Nous devons initialiser l’objetmockMvc dans la méthode annotée de@Before, pour ne pas avoir besoin de l’initialiser à chaque test.

3.4. Vérifier la configuration du test

Pour notre tutoriel ici, vérifions en fait que nous chargeons correctement l'objetWebApplicationContext (wac). Nous vérifierons également que le bonservletContext est joint:

@Test
public void givenWac_whenServletContext_thenItProvidesGreetController() {
    ServletContext servletContext = wac.getServletContext();

    Assert.assertNotNull(servletContext);
    Assert.assertTrue(servletContext instanceof MockServletContext);
    Assert.assertNotNull(wac.getBean("greetController"));
}

Notez que nous vérifions également que nous avons un beanGreetController.java dans le contexte Web - ce qui garantit que les beans spring sont chargés correctement.

À ce stade, la configuration du test d'intégration est terminée. Voyons comment nous pouvons tester les méthodes de ressources en utilisant l'objetMockMvc.

4. Écriture de tests d'intégration

Dans cette section, nous allons passer en revue le fonctionnement de base disponible via le framework de test.

Nous allons montrer comment envoyer des requêtes avec des variables de chemin et des paramètres. Nous allons également suivre les quelques exemples qui montrent comment affirmer que le nom de vue correct est résolu ou que le corps de la réponse est conforme aux attentes.

Les extraits de code suivants utilisent des importations statiques à partir des classes MockMvcRequestBuilders ouMockMvcResultMatchers.

4.1. Vérifier le nom de la vue

Appelons le point de terminaison/homePage de notre test en tant que:

http://localhost:8080/spring-mvc-test/

or

http://localhost:8080/spring-mvc-test/homePage

Extrait de code:

@Test
public void givenHomePageURI_whenMockMVC_thenReturnsIndexJSPViewName() {
    this.mockMvc.perform(get("/homePage")).andDo(print())

      .andExpect(view().name("index"));
}

Décomposons cela:

  • La méthodeperform() appellera une méthode get request qui retourne lesResultActions. En utilisant ce résultat, nous pouvons avoir des attentes d'assertions sur la réponse telles que contenu, statut HTTP, en-tête, etc.

  • andDo(print()) imprimera la demande et la réponse. Ceci est utile pour obtenir une vue détaillée en cas d'erreur

  • andExpect() attendra l'argument fourni. Dans notre cas, nous nous attendons à ce que «index» soit renvoyé viaMockMvcResultMatchers.view()

4.2. Vérifier le corps de la réponse

Nous allons appeler le point de terminaison/greetde notre test comme:

http://localhost:8080/spring-mvc-test/greet

Production attendue:

{
    "id": 1,
    "message": "Hello World!!!"
}

Extrait de code:

@Test
public void givenGreetURI_whenMockMVC_thenVerifyResponse() {
    MvcResult mvcResult = this.mockMvc.perform(get("/greet"))
      .andDo(print()).andExpect(status().isOk())
      .andExpect(jsonPath("$.message").value("Hello World!!!"))
      .andReturn();

    Assert.assertEquals("application/json;charset=UTF-8",
      mvcResult.getResponse().getContentType());
}

Voyons exactement ce qui se passe:

  • andExpect(MockMvcResultMatchers.status().isOk()) vérifiera que l'état de la réponse http estOk, c'est-à-dire 200. Cela garantit que la demande a été exécutée avec succès

  • andExpect(MockMvcResultMatchers.jsonPath(“$.message”).value(“Hello World!!!”)) vérifiera que le contenu de la réponse correspond à l'argument «Hello World!!!». Ici, nous avons utiliséjsonPath qui extrait le contenu de la réponse et fournit la valeur demandée

  • andReturn() retournera l'objetMvcResult qui est utilisé, lorsque nous devons vérifier quelque chose qui n'est pas réalisable par la bibliothèque. Vous pouvez voir que nous avons ajoutéassertEquals pour correspondre au type de contenu de la réponse qui est extrait de l'objetMvcResult

4.3. Envoyer une requêteGET avec une variable de chemin

Nous allons appeler le point de terminaison/greetWithPathVariable/{name}de notre test comme:

http://localhost:8080/spring-mvc-test/greetWithPathVariable/John

Production attendue:

{
    "id": 1,
    "message": "Hello World John!!!"
}

Extrait de code:

@Test
public void givenGreetURIWithPathVariable_whenMockMVC_thenResponseOK() {
    this.mockMvc
      .perform(get("/greetWithPathVariable/{name}", "John"))
      .andDo(print()).andExpect(status().isOk())

      .andExpect(content().contentType("application/json;charset=UTF-8"))
      .andExpect(jsonPath("$.message").value("Hello World John!!!"));
}

MockMvcRequestBuilders.get(“/greetWithPathVariable/{name}”, “John”) enverra la demande en tant que «/greetWithPathVariable/John».

Cela devient plus facile en ce qui concerne la lisibilité et en sachant quels sont les paramètres définis dynamiquement dans l’URL. Cette méthode ne limite pas la transmission du nombre de paramètres de chemin.

4.4. Envoyer la requêteGET avec les paramètres de requête

Nous allons appeler le point de terminaison/greetWithQueryVariable?name={name}de notre test comme:

http://localhost:8080/spring-mvc-test
  /greetWithQueryVariable?name=John%20Doe

Production attendue:

{
    "id": 1,
    "message": "Hello World John Doe!!!"
}

Extrait de code:

@Test
public void givenGreetURIWithQueryParameter_whenMockMVC_thenResponseOK() {
    this.mockMvc.perform(get("/greetWithQueryVariable")
      .param("name", "John Doe")).andDo(print()).andExpect(status().isOk())
      .andExpect(content().contentType("application/json;charset=UTF-8"))
      .andExpect(jsonPath("$.message").value("Hello World John Doe!!!"));
}

param(“name”, “John Doe”) ajoutera le paramètre de requête dans la requêteGET. C'est similaire à «/greetWithQueryVariable?name=John%20Doe“.

Le paramètre de requête peut également être implémenté à l'aide du style de modèle d'URI:

this.mockMvc.perform(
  get("/greetWithQueryVariable?name={name}", "John Doe"));

4.5. Envoyer la requêtePOST

Nous allons appeler le point de terminaison/greetWithPostde notre test comme:

http://localhost:8080/spring-mvc-test/greetWithPost

Production attendue:

{
    "id": 1,
    "message": "Hello World!!!"
}

Extrait de code:

@Test
public void givenGreetURIWithPost_whenMockMVC_thenVerifyResponse() {
    this.mockMvc.perform(post("/greetWithPost")).andDo(print())
      .andExpect(status().isOk()).andExpect(content()
      .contentType("application/json;charset=UTF-8"))
      .andExpect(jsonPath("$.message").value("Hello World!!!"));
}

MockMvcRequestBuilders.post(“/greetWithPost”) enverra la demande de publication. Les variables de chemin et les paramètres de requête peuvent être définis de la même manière que nous l'avons vu précédemment, tandis que les données de formulaire peuvent être définies via la méthodeparam() uniquement de la même manière que le paramètre de requête comme:

http://localhost:8080/spring-mvc-test/greetWithPostAndFormData

Données de formulaire:

id=1;name=John%20Doe

Production attendue:

{
    "id": 1,
    "message": "Hello World John Doe!!!"
}

Extrait de code:

@Test
public void givenGreetURIWithPostAndFormData_whenMockMVC_thenResponseOK() {
    this.mockMvc.perform(post("/greetWithPostAndFormData").param("id", "1")
      .param("name", "John Doe")).andDo(print()).andExpect(status().isOk())

      .andExpect(content().contentType("application/json;charset=UTF-8"))
      .andExpect(jsonPath("$.message").value("Hello World John Doe!!!"))
      .andExpect(jsonPath("$.id").value(1));
}

Dans l'extrait de code ci-dessus, nous avons ajouté 2 paramètres id en tant que «1» et nom en tant que «John Doe».

5. Conclusion

Dans ce rapide tutoriel, nous avons implémenté quelques tests d'intégration simples activés par Spring.

Nous avons également examiné la création d'objetsWebApplicationContext etMockMVC qui jouaient un rôle important dans l'appel des points de terminaison de l'application.

En regardant plus loin, nous avons expliqué comment envoyer les requêtesGET etPOST avec des variations de passage de paramètres et comment vérifier l'état, l'en-tête et le contenu de la réponse HTTP.

Enfin, l'implémentation de tous ces exemples et extraits de code est disponible danshttps://github.com/eugenp/tutorials/tree/master/spring-mvc-java.