2016-07-03 22 views
8

Tôi có một vài mã hoạt động để thiết lập MockMVc theo các cách khác nhau với Khởi động mùa xuân mới 1.4 @WebMvcTest. Tôi hiểu cách tiếp cận standaloneSetup. Điều tôi muốn biết là sự khác biệt giữa việc thiết lập MockMvc đến WebApplicationContext và bằng cách tự động điền MockMvc.Thiết lập MockMvc với @WebMvcTest trong Spring Boot 1.4 Kiểm tra MVC

Code Snippet 1: MockMvc qua WebApplicationContext Cài đặt

@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(); 
    } 
} 

Theo WebMvcTest tài liệu API, Theo mặc định, kiểm tra chú thích với @WebMvcTest cũng sẽ tự động cấu hình Xuân An và MockMvc. Vì vậy, tôi đã dự kiến ​​mã trạng thái không được phép 401 ở đây, nhưng thử nghiệm được chuyển với mã trạng thái 200.

Tiếp theo, tôi đã cố gắng tự động dây MockMvc, nhưng các thử nghiệm không thành công với 401 mã trạng thái trái phép, trừ khi tôi thêm @AutoConfigureMockMvc(secure=false) hoặc cập nhật @WebMvcTest chú thích để vô hiệu hóa bảo mật:

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


Tiếp theo là mã mà đi CHỈ SAU vô hiệu hóa bảo mật một cách rõ ràng.

Code Snippet 2: MockMvc qua 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(); 
    } 
} 

Vì vậy, câu hỏi của tôi là:

  1. Tại sao không Mã đoạn mã 1 báo cáo aa 401 Unauthorized lỗi mã trạng thái trong khi tự động dây MockMvc làm . Ngoài ra, nhắc lại những gì tài liệu chính thức nói Theo mặc định, các bài kiểm tra được chú thích bằng @WebMvcTest cũng sẽ tự động định cấu hình Spring Security và MockMvc. Nhưng, trong trường hợp này, nó xuất hiện @WebMvcTest không liên quan gì đến việc tự động định cấu hình Spring Security (Vì Đoạn mã 1 đi qua mà không có bất kỳ lỗi 401 nào). Cuối cùng nó cũng tóm tắt cách tôi thiết lập MockMvc. Tôi có đúng ở đây không?

  2. Sự khác biệt/mục tiêu giữa/của cả hai cách tiếp cận là gì?

  3. Cách tắt bảo mật qua @AutoConfigureMockMvc(secure=false) khác với việc thực hiện qua @WebMvcTest(controllers = IndexController.class, secure = false). Cái nào được ưu tiên tiếp cận hoặc khi nào (hoặc ở đâu) để sử dụng chúng?

Trả lời

6

Tôi cũng gặp phải vấn đề tương tự. @WebMvcTest tự động cấu hình Spring Security với auth cơ bản nhưng tôi có một lớp WebSecurityConfig mở rộng WebSecurityConfigurerAdapter. Trong lớp này, tôi vô hiệu hóa auth cơ bản và bảo mật cơ sở mã thông báo được cấu hình. Điều đó có nghĩa là lớp WebSecurityConfig không được sử dụng để cấu hình Spring Security.

Để giải quyết sự cố, tôi đã thêm @ContextConfiguration vào lớp thử nghiệm đơn vị của mình và thêm các trình phụ thuộc của lớp 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

Theo vấn đề này trong github

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

auto @WebMvcTest cấu hình theo mặc định, một auth cơ bản khi mùa xuân-an ninh-test là trong đường dẫn lớp

Trả lời câu hỏi của bạn :

  1. Trong đoạn mã 1, bạn không được tiêm thứ e MockMvc trong lớp thử nghiệm của bạn, bạn nên thêm .apply (springSecurity()) vào trình xây dựng trên phương thức thiết lập, vì vậy mùa xuân sẽ sử dụng cấu hình cơ bản (không phải cấu hình bảo mật tùy chỉnh của bạn nếu bạn có). điều tương tự, sự khác biệt là thứ hai đi kèm với auth cơ bản đã có trong MockMvc, đó là lý do tại sao bạn cần phải sử dụng an toàn = false
  2. Từ các tài liệu:

Theo mặc định, kiểm tra được chú thích bằng @WebMvcTest cũng sẽ tự động định cấu hình Bảo mật mùa xuân và MockMvc (bao gồm hỗ trợ cho HtmlUnit WebClient và Selenium WebDriver). Để kiểm soát chi tiết hơn MockMVC, chú thích @AutoConfigureMockMvc có thể được sử dụng.

2

Tôi không chắc chắn điều này có liên quan trực tiếp, nhưng có một outstanding bug ở đâu, nếu sử dụng khởi động mùa xuân và @WebMvcTest, tùy chỉnh @EnableWebSecurity lớp cấu hình của bạn sẽ bị bỏ qua. Một vài cách giải quyết được đề cập trong báo cáo lỗi. Tôi đang sử dụng:

@WebMvcTest(includeFilters = @Filter(classes = EnableWebSecurity.class)) 
Các vấn đề liên quan