2012-09-06 20 views
11

मेरे पास ब्राउज़र नामक पीओजेओ है जिसे मैंने हाइबरनेट वैलिडेटर एनोटेशन के साथ एनोटेट किया है।मैं जुनीट परीक्षण में सत्यापन का आह्वान करने के लिए स्प्रिंग एमवीसी कैसे प्राप्त करूं?

import org.hibernate.validator.constraints.NotEmpty; 

public class Browser { 

    @NotEmpty 
    private String userAgent; 
    @NotEmpty 
    private String browserName; 

... 

} 

मैंने निम्न यूनिट परीक्षण लिखा है जो मेरी नियंत्रक विधि सत्यापन सत्यापन त्रुटियों को सत्यापित करने का प्रयास करता है।

@Test 
public void testInvalidData() throws Exception { 
    Browser browser = new Browser("opera", null); 
    MockHttpServletRequest request = new MockHttpServletRequest(); 

    BindingResult errors = new DataBinder(browser).getBindingResult(); 
    // controller is initialized in @Before method 
    controller.add(browser, errors, request); 
    assertEquals(1, errors.getErrorCount()); 
} 

यहाँ मेरी नियंत्रक जोड़ने() विधि है:

@RequestMapping(value = "/browser/create", method = RequestMethod.POST) 
public String add(@Valid Browser browser, BindingResult result, HttpServletRequest request) throws Exception { 
    if (result.hasErrors()) { 
     request.setAttribute("errorMessage", result.getAllErrors()); 
     return VIEW_NAME; 
    } 

    browserManager.save(browser); 

    request.getSession(false).setAttribute("successMessage", 
      String.format("Browser %s added successfully.", browser.getUserAgent())); 

    return "redirect:/" + VIEW_NAME; 
} 

समस्या मैं का सामना कर रहा है कि परिणाम है कभी नहीं त्रुटियाँ हैं, तो जैसे @Valid मान्यता प्राप्त नहीं हो रही है यह है। मैंने अपनी टेस्ट क्लास में निम्नलिखित जोड़ने का प्रयास किया, लेकिन यह समस्या का समाधान नहीं करता है।

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration({"file:path-to/WEB-INF/spring-mvc-servlet.xml"}) 

क्या किसी को पता है कि मैं जुनीट के साथ परीक्षण करते समय @ वैलिड को मान्यता प्राप्त (और मान्य) कैसे प्राप्त करूं?

धन्यवाद,

मैट

उत्तर

3

सत्यापन नियंत्रक को कॉल करने से पहले किया जाता है, तो अपने परीक्षण इस मान्यता लागू नहीं है।

नियंत्रकों का परीक्षण करने के लिए एक और तरीका है, जहां आप सीधे नियंत्रक का आह्वान नहीं करते हैं। इसके बजाय आप यूआरएल का निर्माण और कॉल करते हैं जिस पर नियंत्रक मैप किया गया है। यहां ऐसा करने के लिए का एक अच्छा उदाहरण है: http://rstoyanchev.github.com/spring-31-and-mvc-test/#1

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(loader=WebContextLoader.class, locations = {"classpath:/META-INF/spring/applicationContext.xml", "classpath:/META-INF/spring/applicationContext-test-override.xml", "file:src/main/webapp/WEB-INF/spring/webmvc-config.xml"}) 
public class MyControllerTest { 
@Autowired 
WebApplicationContext wac; 
MockMvc mockMvc; 

@Before 
public void setup() { 
    this.mockMvc = MockMvcBuilders.webApplicationContextSetup(this.wac).build(); 
} 

@Test 
@Transactional 
public void testMyController() throws Exception { 
    this.mockMvc.perform(get("/mycontroller/add?param=1").accept(MediaType.TEXT_HTML)) 
    .andExpect(status().isOk()) 
    .andExpect(model().attribute("date_format", "M/d/yy h:mm a")) 
    .andExpect(model().attribute("myvalue", notNullValue())) 
    .andExpect(model().attribute("myvalue", hasSize(2))) 
    .andDo(print()); 
} 
} 

पोम (वसंत मील का पत्थर रेपो उपयोग करने की आवश्यकता):

<!-- required for spring-test-mvc --> 
    <repository> 
     <id>spring-maven-milestone</id> 
     <name>Spring Maven Milestone Repository</name> 
     <url>http://maven.springframework.org/milestone</url> 
    </repository> 
... 
    <dependency> 
     <groupId>org.springframework</groupId> 
     <artifactId>spring-test-mvc</artifactId> 
     <version>1.0.0.M1</version> 
     <scope>test</scope> 
    </dependency> 

नोट: वसंत-MVC-परीक्षण lib उत्पादन तैयार नहीं है अभी तक। कार्यान्वयन में कुछ अंतराल हैं। मुझे लगता है कि इसकी योजना वसंत 3.2 के लिए पूरी तरह कार्यान्वित की जाएगी।

यह दृष्टिकोण एक अच्छा विचार है क्योंकि यह आपके नियंत्रकों को पूरी तरह से परीक्षण करता है। अपने कंट्रोलर मैपिंग को गड़बड़ करना आसान है, इसलिए इन्हें वास्तव में यूनिट परीक्षण करने की आवश्यकता है।

2

विधि पैरामीटर के अनुरोध को बाध्य करने की प्रक्रिया के दौरान मान्यकर्ताओं को नियंत्रक विधियों से पहले बुलाया जाता है। चूंकि इस मामले में आप सीधे नियंत्रक विधि का आह्वान कर रहे हैं, बाध्यकारी और सत्यापन चरणों को छोड़ दिया जा रहा है।

इसे काम करने का तरीका स्प्रिंग एमवीसी स्टैक के माध्यम से नियंत्रक को कॉल करना होगा - ऐसा करने के कुछ तरीके हैं, मुझे लगता है कि spring-test-mvc का उपयोग करने का सबसे अच्छा तरीका है जो एक अच्छा तंत्र प्रदान करता है ढेर के माध्यम से बुलाओ।

@Autowired 
private RequestMappingHandlerAdapter handlerAdapter; 

परीक्षा में फिर:

MockHttpServletRequest request = new MockHttpServletRequest("POST","/browser/create"); 
MockHttpServletResponse response = new MockHttpServletResponse(); 
httpRequest.addParameter(....);//whatever is required to create Browser.. 
ModelAndView modelAndView = handlerAdapter.handle(httpRequest, response, handler); 
2

मूल रूप से आप this.controller = new MyController() के साथ एक POJO instantiated, तो

एक और तरीका है ढेर के माध्यम से कॉल करने के लिए HandlerAdapter में परीक्षण करने के लिए इस तरह से इंजेक्षन करने के लिए है इसकी विधि this.controller.add(...) कहा जाता है। बिना किसी संदर्भ के, साधारण वस्तु के साथ बस सरल जावा: @ वालिद को ध्यान में नहीं रखा जाता है।

@ कॉन्टेक्स्ट कॉन्फ़िगरेशन संभवतः संभावित कस्टम सत्यापनकर्ताओं के साथ आपके संभावित बीन्स लोड करेगा, लेकिन यह @ वैलिड प्रोसेसिंग का जादू नहीं करेगा।

आपको नियंत्रक की add विधि के अनुरोध को अनुकरण करने के लिए कुछ चाहिए। इसे पूरी तरह से अनुकरण, सत्यापन शामिल है। आप ऐसा करने से बहुत दूर नहीं थे, क्योंकि आपने कुछ स्प्रिंग परीक्षण सुविधाओं का उपयोग किया था (एक MockHttpServletRequest को तत्काल करने के लिए)।

आप स्प्रिंग 3.0.x या उससे कम का उपयोग करते हैं, तो आप

new AnnotationMethodHandlerAdapter() 
     .handle(request, new MockHttpServletResponse(), this.controller); 

यह काम करने के लिए क्या करने की जरूरत।

यदि आप वसंत 3.1+ का उपयोग करते हैं, तो उपर्युक्त समाधान काम नहीं करेगा (see this link for more info)! आपको this library (स्प्रिंग टीम से, इसलिए यह आवाज चिंता न करें) का उपयोग करने की आवश्यकता होगी, जबकि उन्हें अगले वसंत संस्करण में एकीकृत करने का इंतजार है। तो फिर तुम भी ये बहुत interesting slides रोसन Stoyanchev से पर एक नजर है

myMockController = MockMvcBuilders.standaloneSetup(new MyController()).build(); 
myMockController.perform(get("/browser/create")).andExpect(...); 

की तरह कुछ करना होगा (भाग हम यहाँ के बारे में बात कर रहे हैं स्लाइड # 116 में शुरू होता है)!

नोट: मैं इस तरह के परीक्षण को यूनिट परीक्षण या एकीकरण परीक्षण के रूप में माना जाता है या नहीं, इस बहस में प्रवेश नहीं करूंगा। कुछ लोग कहेंगे कि यह एकीकरण परीक्षण है जिसे हम यहां कर रहे हैं, क्योंकि हम अनुरोध के पूर्ण पथ का अनुकरण करते हैं। लेकिन एक और हाथ पर आप अभी भी अपने नियंत्रक को मॉकिटो से @ मॉक एनोटेशन (या किसी अन्य मॉकिंग फ्रेमवर्क के साथ समान सामान) के साथ नकल कर सकते हैं, इसलिए कुछ अन्य लोग कहेंगे कि आप परीक्षण के दायरे को लगभग शुद्ध "इकाई परीक्षण" में कम कर सकते हैं। । बेशक आप वैकल्पिक रूप से और विशुद्ध रूप से इकाई को अपने पुराने नियंत्रक को सादे पुराने जावा + एक मॉकिंग फ्रेमवर्क के साथ परीक्षण कर सकते हैं, लेकिन इस मामले में यह आपको @ वैलिड सत्यापन का परीक्षण करने की अनुमति नहीं देगा। अपनी पसंद करें ! :)