[JAVA] Comment écrire un test unitaire pour Spring Boot 2

introduction

Depuis que j'ai décidé d'écrire un test unitaire avec spring boot2, J'organiserai le style d'écriture.

Comment écrivez-vous un test de la valeur définie dans Model? J'espère que vous pourrez l'utiliser pour vous en souvenir dans de tels cas.

Un exemple de code est donné sur GitHub.

Test de l'état de la réponse


import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

this.mockMvc.perform(get("/")).andDo(print())
        //Renvoyer ou non le statut "200 OK"
        .andExpect(status().isOk())
        .andExpect(status().is(200))

La documentation ressemble à ici.

Les deux isOk () et is (200) donnent le même résultat.

fichier de modèle thymeleaf

@Controller
@EnableAutoConfiguration
public class HomeController {
  @GetMapping(path = "/")
  String home(HttpServletRequest request, Model model) {
    // home.Spécifiez html
    return "home";
  }
}

Avec ce sentiment, vous retournerez le fichier de modèle de thymeleaf. C'est un test.

    //tester
    this.mockMvc.perform(get("/")).andDo(print())
        //S'il faut renvoyer le modèle "à la maison"
        .andExpect(view().name("home"))

Testez avec la méthode du nom. La documentation est ici.

Test de modèle

Vous emballez les données dans le modèle avec le contrôleur.

MyData.java


public class MyData {
  private String strData;
  private int intData;

  public MyData(String strData, int intData) {
    this.strData = strData;
    this.intData = intData;
  }

  public void setStrData(String strData) {
    this.strData = strData;
  }
  public String getStrData() {
    return this.strData;
  }

  public void setIntData(int intData) {
    this.intData = intData;
  }
  public int getIntData() {
    return this.intData;
  }
}

HomeController.java


@Controller
@EnableAutoConfiguration
public class HomeController {
  @GetMapping(path = "/")
  String home(HttpServletRequest request, Model model) {

    // string
    model.addAttribute("test", "this is test");

    // HashMap<String, String>
    HashMap<String, String> map = new HashMap<String, String>();
    map.put("name", "momotaro");
    map.put("age", "23");
    model.addAttribute("map", map);

    // List<String>
    List<String> list = new ArrayList<String>();
    list.add("list1");
    list.add("list2");
    list.add("list3");
    model.addAttribute("list", list);

    // List<MyData>
    List<MyData> list2 = new ArrayList<MyData>();
    list2.add(new MyData("test1", 111));
    list2.add(new MyData("test2", 222));
    model.addAttribute("list2", list2);

    // home.Spécifiez html
    return "home";
  }
}

HomeControllerTest.java


@SpringBootTest(classes = HomeController.class)
@AutoConfigureMockMvc
public class HomeControllerTest {
  @Autowired
  private MockMvc mockMvc;

  @Test
écran d'accueil vide() throws Exception {

    HashMap<String, String> map = new HashMap<String, String>();
    map.put("name", "momotaro");
    map.put("age", "23");

    List<String> list = new ArrayList<String>();
    list.add("list1");
    list.add("list2");
    list.add("list3");

    List<MyData> list2 = new ArrayList<MyData>();
    list2.add(new MyData("test1", 111));
    list2.add(new MyData("test2", 222));


    //tester
    this.mockMvc.perform(get("/")).andDo(print())
        //Renvoyer ou non le statut "200 OK"
        .andExpect(status().isOk())
        .andExpect(status().is(200))

        //S'il faut renvoyer le modèle "à la maison"
        .andExpect(view().name("home"))

        //Test de modèle.

        //type de chaîne
        .andExpect(model().attribute("test", "this is test"))

        //Type de HashMap
        .andExpect(model().attribute("map", map))

        // List<String>Moule
        .andExpect(model().attribute("list", hasSize(3)))   //Taille de la liste
        .andExpect(model().attribute("list", hasItem("list1")))   //Est-ce que list1 est inclus
        .andExpect(model().attribute("list", hasItem("list2")))   //Est-ce que list2 est inclus
        .andExpect(model().attribute("list", hasItem("list3")))   //Est-ce que list3 est inclus
        .andExpect(model().attribute("list", contains("list1", "list2", "list3")))  // list1, list2,Est-il inclus dans l'ordre de list3?
        .andExpect(model().attribute("list", is(list)))  //S'il correspond à la liste

        // List<MyData>Moule
        .andExpect(model().attribute("list2", hasSize(2)))   //Taille de la liste
        .andExpect(model().attribute("list2",
          hasItem(allOf(hasProperty("strData", is("test1")), hasProperty("intData", is(111))))
        ))   //Cette combinaison de données est-elle incluse?
        .andExpect(model().attribute("list2",
          hasItem(allOf(hasProperty("strData", is("test2")), hasProperty("intData", is(222))))
        ))   //Cette combinaison de données est-elle incluse?
        //.andExpect(model().attribute("list2", is(list2)))  //S'il correspond à list2->Cette façon d'écrire n'est pas possible. Une erreur se produira.

        ;
  }
}

Vous pouvez tester avec la méthode d'attribut comme ceci. Le document est ici

test de redirection

Il sera redirigé par le traitement POST.

HomeController.java


  @PostMapping(path = "/testpost")
  public ModelAndView testpost(RedirectAttributes redirectAttributes,  @RequestParam(value = "intvalue", required = false, defaultValue = "0") Integer intvalue) {
    ModelAndView modelAndView = new ModelAndView("redirect:/testget");

    //Vérifier la valeur d'entrée
    if (intvalue <= 0) {
      redirectAttributes.addFlashAttribute("error", "intvalue doit être supérieur à 0");
      return modelAndView;
    }
    //Définir les données
    modelAndView.addObject("value", intvalue);
    return modelAndView;
  }

HomeControllerTest.java


  @Test
  void testpost() throws Exception {
    //Si vous ne passez pas le paramètre, il sera pris dans la vérification
    this.mockMvc.perform(post("/testpost")).andExpect(redirectedUrl("/testget"))
        .andExpect(flash().attribute("error", "intvalue doit être supérieur à 0"));

    //Passer le contrôle après avoir passé les paramètres
    this.mockMvc.perform(post("/testpost").param("intvalue", "5"))
        .andExpect(redirectedUrl("/testget?value=5"));
  }

Utilisez redirectedUrl () pour tester l'URL de destination.

Utilisez flash () pour tester redirectAttributes.addFlashAttribute ().

Les paramètres reçus par POST peuvent être spécifiés par param ().

Tester si une méthode particulière a été appelée avec un argument particulier

Lors de la réception du POST sur le contrôleur Je pense que je vais faire quelque chose à ce sujet. Ce test.

Ici, DI un service spécifique au contrôleur Testons l'appel de la méthode Servcie dans le processus Post.

MyService.java


@Service
public class MyService {
  public void test(int value) {
    System.out.println("MyService.test()..." + value);
  }
}

HomeController.java



@Controller
@EnableAutoConfiguration
public class HomeController {

  @Autowired
  MyService myService;

  @PostMapping(path = "/testpost2")
  public String testpost2(@RequestParam(value = "intvalue", required = false, defaultValue = "0") Integer intvalue) {

    //Test MyService()Appel
    myService.test(intvalue);

    return "redirect:/";
  }
}

HomeControllerTest.java


@SpringBootTest(classes = HomeController.class)
@AutoConfigureMockMvc
public class HomeControllerTest {
  @Autowired
  private MockMvc mockMvc;

  @MockBean
  private MyService myService;

  @Test
  void testpos2() throws Exception {
    //redirectUrl vérification
    this.mockMvc.perform(post("/testpost2").param("intvalue", "5")).andExpect(redirectedUrl("/"));

    //Test MyService()Teste si la méthode a été appelée avec une valeur d'argument de 5
    verify(this.myService, times(1)).test(5);
  }
}

verify(this.myService, times(1)).test(5);

Si vous écrivez "La méthode de test de la classe MyService a été appelée une fois avec une valeur d'argument de 5" Ce sera un test.

Le test pour voir s'il a été appelé deux fois

verify(this.myService, times(2)).test(5);

Et

Lorsque vous voulez que la valeur de l'argument soit 10

verify(this.myService, times(1)).test(10);

Écrire.

par ça, Le test du contrôleur Vérification de la valeur du paramètre pour isoler le processus, Passer des valeurs de paramètres à des fonctions d'autres services Je pense que cela peut être réduit à deux types.

Test des paramètres Get

Les paramètres Post ont été spécifiés dans params (), Les paramètres Get sont spécifiés par URL.

HomeController.java


  @GetMapping(path = "/testget")
  String testget(@RequestParam(value = "value", required = false, defaultValue = "0") Integer value, @ModelAttribute("error") String error, Model model) {

    model.addAttribute("strError", error);
    model.addAttribute("intValue", value);

    // testget.Spécifiez html
    return "testget";
  }

HomeControllerTest.java


  @Test
  void testget() throws Exception {
    this.mockMvc.perform(get("/testget?value=5&error=SuperError")).andDo(print())
        //Renvoyer ou non le statut "200 OK"
        .andExpect(status().isOk())

        //S'il faut renvoyer le modèle "testget"
        .andExpect(view().name("testget"))

        //Test de modèle.
        .andExpect(model().attribute("intValue", 5))
        .andExpect(model().attribute("strError", "SuperError"))
        ;
  }

en conclusion

C'est toujours un mémo quand j'ai commencé à écrire des tests avec Spring Boot, donc Je voudrais continuer à en ajouter.

Un exemple de code est donné sur GitHub.

fin.

Recommended Posts

Comment écrire un test unitaire pour Spring Boot 2
Comment faire un test unitaire de Spring AOP
[Spring Boot] Comment créer un projet (pour les débutants)
Je veux écrire un test unitaire!
[SpringBoot] Comment écrire un test de contrôleur
Comment créer un hinadan pour un projet Spring Boot à l'aide de SPRING INITIALIZR
Exemple de code pour le test unitaire d'un contrôleur Spring Boot avec MockMvc
Écrivons un code de test pour la fonction de connexion avec Spring Boot
Comment ajouter un chemin de classe dans Spring Boot
Comment définir l'injection de dépendance Spring Boot (DI)
[Compatible JUnit 5] Ecrire un test en utilisant JUnit 5 avec Spring boot 2.2, 2.3
Comment créer un projet Spring Boot dans IntelliJ
[JUnit 5] Ecrivez un test de validation avec Spring Boot! [Test de paramétrage]
Comment écrire dynamiquement des cas de test itératifs à l'aide de test / unit (Test :: Unit)
Écrire du code de test avec Spring Boot
Comment configurer Spring Boot + PostgreSQL
Utiliser DBUnit pour le test Spring Boot
Comment utiliser ModelMapper (Spring boot)
Utilisez Spring Test + Mockito + JUnit 4 pour le test unitaire Spring Boot + Spring Retry
[Basique] Comment écrire un auto-apprentissage Dockerfile ②
[R Spec on Rails] Comment écrire du code de test pour les débutants par les débutants
[Introduction à Java] Comment écrire un programme Java
Comment créer un référentiel Maven pour 2020
Comment écrire un spécificateur de coupe de point Spring AOP
Comment diviser un fichier de message Spring Boot
[Rspec] Flux de l'introduction de Rspec à l'écriture du code de test unitaire pour le modèle
Rails: comment bien écrire une tâche de râteau
[Java] Comment tester s'il est nul dans JUnit
À propos de la conception de Spring Boot et de l'environnement de test unitaire
Comment créer une base de données H2 n'importe où
[Rails] Comment écrire lors de la création d'une sous-requête
Comment utiliser MyBatis2 (iBatis) avec Spring Boot 1.4 (Spring 4)
Comment utiliser h2db intégré avec Spring Boot
Comment réduire l'image de Spring Boot Docker
JUnit 5: Comment écrire des cas de test dans enum
Comment utiliser les attributs de session Spring Boot (@SessionAttributes)
Comment créer des pages pour le tableau "kaminari"
[Rails] Comment implémenter un test unitaire d'un modèle
Comment créer un JRE léger pour la distribution
Comment écrire du code de test avec la certification de base
Comment se lier avec un fichier de propriétés dans Spring Boot
[Spring Boot] Comment se référer au fichier de propriétés
Spring Boot - Comment définir le délai d'expiration de la session
Comment écrire des rails
Comment afficher les caractères saisis dans Spring Boot sur le navigateur et les liens de référence [Introduction à Spring Boot / Pour les débutants]
Comment écrire docker-compose
Comment écrire Mockito
Comment écrire un fichier de migration
[Spring Boot] Comment obtenir des propriétés dynamiquement à partir d'une chaîne contenue dans une URL
Comment effectuer UT avec Excel en tant que données de test avec Spring Boot + JUnit5 + DBUnit
Plans pour prendre en charge JDK 11 pour Eclipse et Spring Boot
Paramètres de connexion à MySQL avec Spring Boot + Spring JDBC
Comment utiliser un tableau pour la clé TreeMap
Comment faire un test unitaire avec JVM sur une source à l'aide de RxAndroid
Un mémorandum de dépendance à Spring Boot2 x Doma2