2015-03-14 18 views
50

mam przykładową aplikację Wiosna rozruchu z następnegoJak napisać testów jednostkowych dla punktu końcowego Wiosna Boot Controller

Boot głównej klasy

@SpringBootApplication 
public class DemoApplication { 

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

Controller

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

} 

Jaki jest najłatwiejszy sposób na napisanie testu jednostkowego dla kontrolera? Próbowałem następujących ale narzeka braku do autowire 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() { 
    } 

} 
+3

Spróbuj opisać 'DemoApplication' za pomocą' @ WebAppConfiguration'. Jeśli to nie zadziała, czy możesz dodać również kod? – Augusto

Odpowiedz

37

MVC wiosny oferuje standaloneSetup który obsługuje Testowanie stosunkowo prostych sterowników, bez konieczności kontekście.

Zbuduj MockMvc rejestrując jedną lub więcej instancji @ Controller i konfigurując programowo infrastrukturę Spring MVC. To pozwala pełną kontrolę nad instancją i inicjalizacją kontrolerów, i ich zależnościami, podobnie do zwykłych testów jednostkowych, a jednocześnie czyniąc możliwym testowanie jednego kontrolera jednocześnie.

Przykładowy test na kontrolera może być coś tak prostego jak

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")); 

    } 
} 
+0

co robi ten test? Próbowałem go z when (employeeService.getById (1)). ThenReturn (employee); Jeśli potwierdzam zwrot, jak mogę się upewnić, że działa zgodnie z oczekiwaniami? – BigDong

+0

w tym przykładzie omówiono jedynie podstawowe oczekiwania, ale można dalej drążyć przy użyciu matowania Hamcrest i potwierdzić cokolwiek w ciele, np. rzeczywista odpowiedź jsona według tego, czego oczekujesz. Zasadniczo, bez względu na to, czego się spodziewasz z instancją Employee, możesz również stwierdzić, czy jest to transformacja do JSON lub XML, zmiana nazwy właściwości itp. –

+0

. IExpect (content(). ContentType ("application/json")) ; ta linia daje mi błąd "Metoda content() jest niezdefiniowana dla typu". – Jesse

4

Dodawanie @WebAppConfiguration (org.springframework.test.context.web.WebAppConfiguration) adnotacji do klasy DemoApplicationTests zadziała.

24

Nowe ulepszenia testowania, które zadebiutowały w Spring Boot 1.4.M2, mogą pomóc w zmniejszeniu ilości kodu potrzebnego do napisania takiej sytuacji.

Test będzie wyglądać tak:

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")); 

     } 

    } 

Zobacz this blogu więcej szczegółów, jak również w documentation

+7

To nie działa. Nadal dostaniesz '' java.lang.IllegalStateException: Nie można znaleźć @SpringBootConfiguration, musisz użyć @ContextConfiguration lub @SpringBootTest (classes = ...) z błędem testowym. – Lucas

+1

Działa to greate z 'spring-boot 1.4.0' i' junit'. –

+0

Nie znalazłem też żadnych problemów ... Byłbym wspaniale mieć powtarzalny przypadek błędu. – geoand

5

Oto kolejna odpowiedź użyciu MVC wiosny za standaloneSetup. Za pomocą tej metody można albo wyposażyć klasę kontrolera, albo w nią przeprowadzić symulację.

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() { 
     } 

    } 
+0

Dostępne są również @SpringBootTest (webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT). – okwap

+0

To działa dla mnie, gdy mam automatyczne pole usługi w kontrolerze, próbowałem używać drogi geograficznej, ale pole serwisowe zawsze ma wartość zerową, nie wiem dlaczego? – eagles

Powiązane problemy