2016-07-03 15 views
8

Mam niewiele działającego kodu, aby skonfigurować MockMVc na różne sposoby dzięki nowemu rozruchowi wiosennemu 1.4 @WebMvcTest. Rozumiem podejście oparte na standaloneSetup. To, co chcę wiedzieć, to różnica między konfiguracją MockMvc do WebApplicationContext i autowiring MockMvc.Konfigurowanie MockMvc przy pomocy @WebMvcTest w Spring Boot 1.4 Testowanie MVC

Code Snippet 1: MockMvc przez WebApplicationContext Konfiguracja

@RunWith(SpringRunner.class) 
@WebMvcTest(controllers = ProductController.class) 
public class ProductControllerTest { 

private MockMvc mockMvc; 

@Autowired 
private WebApplicationContext webApplicationContext; 

@MockBean 
private ProductService productServiceMock; 

@Before 
public void setUp() { 
    mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); 
} 

@Test 
public void testShowProduct() throws Exception {  

    Product product1 = new Product(); 
    /*Code to initialize product1*/ 

    when(productServiceMock.getProductById(1)).thenReturn(product1); 

    MvcResult result = mockMvc.perform(get("/product/{id}/", 1)) 
      .andExpect(status().isOk()) 
      /*Other expectations*/ 
      .andReturn(); 
    } 
} 

Zgodnie WebMvcTest dokumentacji API, Domyślnie, testy opatrzone @WebMvcTest będzie również automatycznie skonfigurować Wiosna Security and MockMvc. Tak więc oczekiwałem tutaj 401 nieautoryzowanego kodu statusu, ale test przechodzi z kodem statusu 200.

Następnie próbowałem auto okablowanie MockMvc, ale test nie powiedzie się z 401 nieautoryzowanego kodu statusu, chyba że dodam @AutoConfigureMockMvc(secure=false) lub zaktualizować @WebMvcTest adnotacji, aby wyłączyć zabezpieczenie:

@WebMvcTest(controllers = IndexController.class, secure = false) 


Poniżej znajduje się kod, który przechodzi TYLKO PO BEZPIECZNYM wyłączeniu bezpieczeństwa.

Code Snippet 2: MockMvc przez autowiring

@RunWith(SpringRunner.class) 
@WebMvcTest(controllers = ProductController.class) 
@AutoConfigureMockMvc(secure=false) 
public class ProductControllerTest { 
@Autowired 
private MockMvc mockMvc; 
@Autowired 
private WebApplicationContext webApplicationContext; 
@MockBean 
private ProductService productServiceMock; 

@Test 
public void testShowProduct() throws Exception {  

    Product product1 = new Product(); 
    /*Code to initialize product1*/ 

    when(productServiceMock.getProductById(1)).thenReturn(product1); 

    MvcResult result = mockMvc.perform(get("/product/{id}/", 1)) 
      .andExpect(status().isOk()) 
      /*Other expectations*/ 
      .andReturn(); 
    } 
} 

Więc moje pytania to:

  1. Dlaczego nie Fragment kodu 1 raportu aa 401 kod błędu podczas auto stan Nieautoryzowany okablowanie MockMvc zrobił . Powtarzam też, co mówi oficjalny dokument: Domyślnie testy opatrzone adnotacją @WebMvcTest również automatycznie konfigurują Spring Security i MockMvc. Jednak w tym przypadku wygląda na to, że @WebMvcTest nie ma nic wspólnego z automatyczną konfiguracją Spring Security (ponieważ fragment kodu 1 przechodzi bez żadnego błędu 401). W końcu sprowadza się to do ustawienia MockMvc. Czy mam tu rację?

  2. Jakie są różnice/cele pomiędzy/obu podejść?

  3. W jaki sposób wyłączenie zabezpieczeń za pomocą @AutoConfigureMockMvc(secure=false) różni się od wykonania przez @WebMvcTest(controllers = IndexController.class, secure = false). Który z nich jest preferowany lub kiedy (lub gdzie) go używać?

Odpowiedz

6

Też mam podobny problem. @WebMvcTest automatycznie konfiguruje Spring Security z podstawowym uwierzytelnieniem, ale mam klasę WebSecurityConfig, która rozszerza WebSecurityConfigurerAdapter. W tej klasie wyłączono podstawowe uwierzytelnianie i skonfigurowałem zabezpieczenia bazy tokenów. Oznacza to, że klasa WebSecurityConfig nie jest używana do konfigurowania Spring Security.

Aby rozwiązać problem, dodałem opcję @ContextConfiguration do mojej klasy testu urządzenia i dodano makra zależności klasy WebSecurityConfig.

@RunWith(SpringRunner.class) 
@WebMvcTest(controllers = CategoryRestService.class) 
@ContextConfiguration(classes={MjApplication.class, WebSecurityConfig.class}) 
public class CategoryRestServiceTest { 

    @MockBean 
    private CategoryRepository repository; 

    @MockBean 
    CurrentUserDetailsService currentUserDetailsService; 

    @MockBean 
    TokenAuthProvider tokenAuthProvider; 

    @Autowired 
    MockMvc mockMvc; 

    private MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(), 
      MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8")); 


    @Test 
    public void getCategories() throws Exception { 
     Category category1 = new Category(); 
     category1.setName("Test Category 1"); 
     category1.setId(1L); 
     Category category2 = new Category(); 
     category2.setName("Test Category 2"); 
     category2.setId(2L); 
     List<Category> categoryList = new ArrayList<Category>(); 
     categoryList.add(category1); 
     categoryList.add(category2); 
     given(this.repository.findAll()) 
     .willReturn(categoryList); 
     mockMvc.perform(get("/public/rest/category")) 
     .andExpect(status().isOk()) 
     .andExpect(content().contentType(contentType)) 
     .andExpect(jsonPath("$[0].id", is(1))) 
     .andExpect(jsonPath("$[0].name", is("Test Category 1"))) 
     .andExpect(jsonPath("$[1].id", is(2))) 
     .andExpect(jsonPath("$[1].name", is("Test Category 2"))); 
    } 

} 
6

Według tej kwestii w github

https://github.com/spring-projects/spring-boot/issues/5476

@WebMvcTest auto konfiguruje domyślnie podstawowy auth kiedy wiosna-security-test jest w ścieżce klasy

Odpowiadając na Twoje pytania :

  1. W części kodu 1 nie wstrzyknięto e MockMvc w twojej klasie testowej, powinieneś dodać .apply (springSecurity()) w budowniczym w metodzie instalacji, więc wiosna użyje podstawowej konfiguracji (nie twojej niestandardowej konfiguracji bezpieczeństwa, jeśli masz)
  2. oba podejścia w zasadzie to samo, różnica jest taka, że ​​drugi pochodzi z podstawowego uwierzytelniania już w MockMvc, dlatego trzeba korzystać z bezpiecznego = false
  3. z dokumentacji:

domyślnie, testy z adnotacją @WebMvcTest będzie również automatycznie konfigurować Spring Security i MockMvc (w tym obsługa HtmlUnit WebClient i Selenium WebDriver). W celu dokładniejszej kontroli MockMVC można użyć adnotacji @AutoConfigureMockMvc.

2

nie jestem pewien, że to jest bezpośrednio związane, ale jest outstanding bug gdzie, jeśli przy użyciu bagażnik sprężyny i @WebMvcTest, niestandardowe @EnableWebSecurity klasa config będą ignorowane. Kilka obejść wymieniono w raporcie o błędzie. Używam:

@WebMvcTest(includeFilters = @Filter(classes = EnableWebSecurity.class)) 
Powiązane problemy