2015-03-14 9 views
50

Ich habe eine Probe Frühling Boot-App mit der folgendenWie ein Unit-Test für einen Frühlings-Boot-Controller Endpunkt

Boot-Hauptklasse

@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!"; 
    } 

} 

Was ist die am einfachsten schreiben Möglichkeit, einen Komponententest für den Controller zu schreiben? Ich habe versucht, die folgenden, aber es beschwert sich über Fehler 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

Versuchen Sie, 'DemoApplication' mit' @ WebAppConfiguration' zu kommentieren. Wenn das nicht funktioniert, können Sie den Code auch hinzufügen? – Augusto

Antwort

37

Spring MVC bietet eine standaloneSetup die Prüfung relativ einfachen Controller unterstützt, ohne die Notwendigkeit von Kontext autowire.

bauen eine MockMvc durch einen oder mehrere @ Kontrolleurs Instanzen zu registrieren und programmatisch Spring MVC-Infrastruktur konfigurieren. Dies ermöglicht vollständige Kontrolle über die Instanziierung und Initialisierung von Controllern, und deren Abhängigkeiten, ähnlich wie bei Unit-Tests, wobei auch es möglich ist, jeweils einen Controller zu testen.

Ein Beispiel Test für Ihren Controller kann als

etwas so einfach sein
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

Was bedeutet dieser Test? Ich habe es mit wann versucht (employeeService.getById (1)). DannReturn (Mitarbeiter); Wenn ich die Rückgabe zertifiziere, wie kann ich sicher sein, dass es wie erwartet funktioniert? – BigDong

+0

In diesem Beispiel werden nur die grundlegenden Erwartungen besprochen, aber Sie können mit den Hamcrest-Matchern weiter nach unten gehen und alles im Körper, z. tatsächliche JSON Antwort von dem, was Sie erwarten. Grundsätzlich können Sie, was auch immer Sie mit der Employee-Instanz erwarten, Assertion angeben, sei es die Umwandlung in JSON oder XML, das Umbenennen von Eigenschaften usw. –

+0

.andExpect (content(). ContentType ("application/json")) ; Diese Zeile gibt mir einen Fehler "Die Methode content() ist für den Typ nicht definiert". – Jesse

4

Hinzufügen @WebAppConfiguration (org.springframework.test.context.web.WebAppConfiguration) Anmerkung zu Ihrem DemoApplicationTests Klasse arbeiten.

24

Die neuen Testverbesserungen, die in Spring Boot 1.4.M2 debütierten, können helfen, die Menge an Code zu reduzieren, die Sie benötigen, um eine Situation wie diese zu schreiben.

Der Test würde wie so aussehen:

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

     } 

    } 

Siehe this Blog-Post für weitere Details sowie die documentation

+7

Dies funktioniert nicht. Sie werden immer noch eine "java.lang.IllegalStateException" erhalten: Es konnte keine @SpringBootConfiguration gefunden werden, Sie müssen @ContextConfiguration oder @SpringBootTest (classes = ...) mit Ihrem test'' Fehler verwenden. – Lucas

+1

Dies funktioniert mit 'Spring-Boot 1.4.0' und' Junit'. –

+0

Ich habe auch keine Probleme gefunden ... Ich wäre großartig, um eine reproduzierbare Fall des Fehlers – geoand

5

Hier ist eine andere Antwort mit Spring MVC standaloneSetup. Auf diese Weise können Sie die Controller-Klasse entweder autowire oder Mock es.

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

Es gibt auch @SpringBootTest (webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) verfügbar. – okwap

+0

Das funktioniert für mich, wenn ich ein autowired Service-Feld in der Steuerung habe, habe ich versucht, geoand Weg, aber das Service-Feld immer Null, weiß nicht warum? – eagles

Verwandte Themen