web-dev-qa-db-fra.com

Comment écrire un test unitaire pour un noeud final Spring Boot Controller

J'ai un exemple d'application Spring Boot avec les éléments suivants

Classe principale de démarrage

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

Manette

@RestController
@EnableAutoConfiguration
public class HelloWorld {
    @RequestMapping("/")
    String gethelloWorld() {
        return "Hello World!";
    }

}

Quel est le moyen le plus simple d'écrire un test unitaire pour le contrôleur? J'ai essayé ce qui suit, mais il se plaint de ne pas avoir réussi à autoriser WebApplicationContext

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = DemoApplication.class)
public class DemoApplicationTests {

    final String BASE_URL = "http://localhost:8080/";

    @Autowired
    private WebApplicationContext wac;

    private MockMvc mockMvc;

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

    @Test
    public void testSayHelloWorld() throws Exception{

         this.mockMvc.perform(get("/")
                 .accept(MediaType.parseMediaType("application/json;charset=UTF-8")))
                 .andExpect(status().isOk())
                 .andExpect(content().contentType("application/json"));
    }

    @Test
    public void contextLoads() {
    }

}
64
user6123723

Spring MVC offre un standaloneSetup qui prend en charge le test de contrôleurs relativement simples, sans avoir besoin de contexte.

Construisez un MockMvc en enregistrant une ou plusieurs instances de @ Controller et en configurant l'infrastructure Spring MVC par programmation. Cela permet un contrôle total de l'instanciation et de l'initialisation des contrôleurs, ainsi que de leurs dépendances, similaire aux tests unitaires standard, tout en permettant de tester un contrôleur à la fois.

Un exemple de test de votre contrôleur peut être aussi simple que

public class DemoApplicationTests {

    private MockMvc mockMvc;

    @Before
    public void setup() {
        this.mockMvc = standaloneSetup(new HelloWorld()).build();
    }

    @Test
    public void testSayHelloWorld() throws Exception {
        this.mockMvc.perform(get("/")
           .accept(MediaType.parseMediaType("application/json;charset=UTF-8")))
           .andExpect(status().isOk())
           .andExpect(content().contentType("application/json"));

    }
}
45
Master Slave

Les nouvelles améliorations de test introduites dans Spring Boot 1.4.M2 peuvent contribuer à réduire la quantité de code nécessaire pour écrire de telles situations.

Le test ressemblerait à ceci:

import static org.springframework.test.web.servlet.request.MockMvcRequestB‌​uilders.get; 
import static org.springframework.test.web.servlet.result.MockMvcResultMat‌​chers.content; 
import static org.springframework.test.web.servlet.result.MockMvcResultMat‌​chers.status;

    @RunWith(SpringRunner.class)
    @WebMvcTest(HelloWorld.class)
    public class UserVehicleControllerTests {

        @Autowired
        private MockMvc mockMvc;

        @Test
        public void testSayHelloWorld() throws Exception {
            this.mockMvc.perform(get("/").accept(MediaType.parseMediaType("application/json;charset=UTF-8")))
                    .andExpect(status().isOk())
                    .andExpect(content().contentType("application/json"));

        }

    }

Voir this blog pour plus de détails ainsi que le documentation

28
geoand

Voici une autre réponse utilisant standaloneSetup de Spring MVC. En utilisant cette méthode, vous pouvez autoriser automatiquement la classe de contrôleurs ou la simuler.

    import static org.mockito.Mockito.mock;
    import static org.springframework.test.web.server.request.MockMvcRequestBuilders.get;
    import static org.springframework.test.web.server.result.MockMvcResultMatchers.content;
    import static org.springframework.test.web.server.result.MockMvcResultMatchers.status;

    import org.junit.Before;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.http.MediaType;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    import org.springframework.test.web.server.MockMvc;
    import org.springframework.test.web.server.setup.MockMvcBuilders;


    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
    public class DemoApplicationTests {

        final String BASE_URL = "http://localhost:8080/";

        @Autowired
        private HelloWorld controllerToTest;

        private MockMvc mockMvc;

        @Before
        public void setup() {
            this.mockMvc = MockMvcBuilders.standaloneSetup(controllerToTest).build();
        }

        @Test
        public void testSayHelloWorld() throws Exception{
            //Mocking Controller
            controllerToTest = mock(HelloWorld.class);

             this.mockMvc.perform(get("/")
                     .accept(MediaType.parseMediaType("application/json;charset=UTF-8")))
                     .andExpect(status().isOk())
                     .andExpect(content().mimeType(MediaType.APPLICATION_JSON));
        }

        @Test
        public void contextLoads() {
        }

    }
6
Siva Kumar

L'ajout d'annotation @WebAppConfiguration (org.springframework.test.context.web.WebAppConfiguration) à votre classe DemoApplicationTests fonctionnera.

4
Charles Wang