2016-07-03 13 views
8

मेरे पास MockMVc को नए स्प्रिंग बूट 1.4 @WebMvcTest के साथ विभिन्न तरीकों से सेट करने के लिए कुछ कार्य कोड हैं। मैं स्टैंडअलोनसेट दृष्टिकोण को समझता हूं। मैं क्या जानना चाहता हूं MockMvcWebApplicationContext के माध्यम से और MockMvc को स्वचालित रूप से सेट करने के बीच अंतर है।स्प्रिंग बूट में @WebMvcTest के साथ MockMvc सेट करना 1.4 एमवीसी परीक्षण

कोड स्निपेट 1: MockMvc WebApplicationContext सेटअप

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

प्रति WebMvcTest API दस्तावेज़ के रूप में, डिफ़ॉल्ट रूप से, @WebMvcTest साथ एनोटेट भी वसंत सुरक्षा और MockMvc ऑटो कॉन्फिगर करेगा परीक्षणों के माध्यम से। इसलिए, मुझे यहां एक 401 अनधिकृत स्टेटस कोड की उम्मीद है, लेकिन परीक्षण 200 स्टेटस कोड के साथ गुजरता है।

इसके बाद, मैं ऑटो तारों MockMvc कोशिश की, लेकिन परीक्षण, 401 अनधिकृत स्थिति कोड के साथ विफल रहता है जब तक कि मैं @AutoConfigureMockMvc(secure=false) जोड़ सकते हैं या सुरक्षा को अक्षम करने @WebMvcTest एनोटेशन अद्यतन:

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


के बाद कोड है कि गुजरता है सुरक्षा को स्पष्ट रूप से अक्षम करने के बाद ही।

कोड स्निपेट 2: MockMvc 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(); 
    } 
} 

के माध्यम से तो मेरी प्रश्न हैं:

  1. कोड क्यों झलकी नहीं था 1 रिपोर्ट आ 401 अनधिकृत स्थिति कोड त्रुटि जबकि ऑटो तारों MockMvc किया । यह भी दोहराता है कि आधिकारिक डॉक्टर डिफ़ॉल्ट रूप से, @WebMvcTest के साथ एनोटेटेड परीक्षण स्प्रिंग सिक्योरिटी और मॉकएमवीसी को स्वतः कॉन्फ़िगर भी करेगा। लेकिन, इस मामले में यह @WebMvcTest को स्प्रिंग सुरक्षा स्वत: कॉन्फ़िगर करने के साथ कुछ भी नहीं है (क्योंकि कोड स्निपेट 1 किसी भी 401 त्रुटि के बिना गुजरता है)। अंततः यह MockMvc को स्थापित करने के लिए उबलता है। क्या मैं यहाँ सही हूँ?

  2. दोनों दृष्टिकोणों के बीच अंतर/उद्देश्यों क्या हैं?

  3. @AutoConfigureMockMvc(secure=false) के माध्यम से सुरक्षा को अक्षम करने से @WebMvcTest(controllers = IndexController.class, secure = false) के माध्यम से क्या करना अलग है। कौन सा पसंदीदा दृष्टिकोण है या जब (या कहां) उनका उपयोग करना है?

उत्तर

6

मैं भी इसी तरह की समस्या में आया हूं। @WebMvcTest ऑटो बुनियादी लेख के साथ स्प्रिंग सिक्योरिटी को कॉन्फ़िगर करता है लेकिन मेरे पास WebSecurityConfig क्लास है जो WebSecurityConfigurerAdapter को बढ़ाती है। इस वर्ग में मैंने मूल लेख और कॉन्फ़िगर किए गए टोकन बेस सुरक्षा को अक्षम कर दिया है। इसका मतलब है कि WebSecurityConfig क्लास का उपयोग वसंत सुरक्षा को कॉन्फ़िगर करने के लिए नहीं किया जाता है।

समस्या को हल करने के लिए, मैंने अपनी यूनिट टेस्ट क्लास में @Context कॉन्फ़िगरेशन जोड़ा और 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
GitHub में इस मुद्दे के अनुसार

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

@WebMvcTest ऑटो, डिफ़ॉल्ट रूप से कॉन्फ़िगर करता है एक मूल प्रमाणीकरण जब वसंत-सुरक्षा-परीक्षण वर्ग पथ

में है आपके प्रश्नों का उत्तर देना :

  1. कोड स्निपेट 1 में, आपने इंजेक्शन नहीं दिया ई टेक क्लास में ई मॉकएमवीसी, आपको सेटअप विधि पर बिल्डर में .apply (springSecurity()) जोड़ना चाहिए, इसलिए वसंत मूल कॉन्फ़िगरेशन का उपयोग करेगा (यदि आपके पास कोई कस्टम सुरक्षा कॉन्फ़िगरेशन नहीं है)
  2. दोनों दृष्टिकोण मूल रूप से करते हैं एक ही बात, अंतर यह है कि इसी कारण आप सुरक्षित उपयोग करने के लिए है कि दूसरी पहले से ही MockMvc में मूल प्रमाणीकरण के साथ आता है = false
  3. प्रलेखन से:

डिफ़ॉल्ट रूप से, परीक्षण @WebMvcTest के साथ एनोटेटेड स्प्रिंग सिक्योरिटी और मॉकएमवीसी को स्वचालित रूप से कॉन्फ़िगर करेगा (एचटीएमएल यूनिट वेब क्लाइंटके लिए समर्थन शामिल करेंऔर सेलेनियम वेबड्राइवर)। MockMVC के अधिक सुदृढ़ नियंत्रण के लिए @AutoConfigureMockMvc एनोटेशन का उपयोग किया जा सकता है।

2

मुझे यकीन है कि यह सीधे संबंधित है नहीं कर रहा हूँ, लेकिन वहाँ एक outstanding bug जहां, अगर वसंत बूट और @WebMvcTest का उपयोग कर, अपने कस्टम @EnableWebSecurity config वर्ग नजरअंदाज कर दिया जाएगा है। बग रिपोर्ट में कुछ कामकाज का उल्लेख किया गया है। मैं उपयोग कर रहा हूं:

@WebMvcTest(includeFilters = @Filter(classes = EnableWebSecurity.class)) 
संबंधित मुद्दे