2010-02-22 15 views
9

मैं उस दिन एक समस्या में भाग गया जहां @ वालिड एनोटेशन को गलती से नियंत्रक वर्ग से हटा दिया गया था। दुर्भाग्य से, यह हमारे किसी भी परीक्षण को तोड़ नहीं दिया। हमारे यूनिट परीक्षणों में से कोई भी वास्तव में वसंत AnnotationMethodHandlerAdapter मार्ग का उपयोग नहीं करता है। हम बस हमारे नियंत्रक कक्षाओं का परीक्षण सीधे करते हैं।परीक्षण स्प्रिंग @ एमवीसी एनोटेशन

मैं एक इकाई या एकीकरण परीक्षण कैसे लिख सकता हूं जो मेरे @ एमवीसी एनोटेशन गलत हैं अगर सही तरीके से असफल हो जाएंगे? क्या कोई तरीका है कि मैं स्प्रिंग से मॉकहट्स्सर्वलेट या कुछ के साथ प्रासंगिक नियंत्रक को ढूंढने और व्यायाम करने के लिए कह सकता हूं?

+1

आप इकाई एक एनोटेशन का परीक्षण नहीं होगा, क्या तुम करोगी? मुझे एक एकीकरण परीक्षण चिंता माना जाता है। –

उत्तर

1

पर अपना ब्लॉग पोस्ट देखें आगामी sprin में जी 3.2 (स्नैपशॉट उपलब्ध) या वसंत-परीक्षण-एमवीसी (https://github.com/SpringSource/spring-test-mvc) के साथ आप इसे इस तरह से कर सकते हैं:

पहले हम सत्यापन को अनुकरण करते हैं क्योंकि हम नहीं चाहते हैं सत्यापनकर्ता का परीक्षण करने के लिए, सिर्फ यह जानना है कि सत्यापन कहा जाता है या नहीं।

public class LocalValidatorFactoryBeanMock extends LocalValidatorFactoryBean 
{ 
    private boolean fakeErrors; 

    public void fakeErrors () 
    { 
     this.fakeErrors = true; 
    } 

    @Override 
    public boolean supports (Class<?> clazz) 
    { 
     return true; 
    } 

    @Override 
    public void validate (Object target, Errors errors, Object... validationHints) 
    { 
     if (fakeErrors) 
     { 
      errors.reject("error"); 
     } 
    } 
} 

यह हमारे परीक्षण वर्ग है:

@RunWith(SpringJUnit4ClassRunner.class) 
@WebAppConfiguration 
@ContextConfiguration 
public class RegisterControllerTest 
{ 
@Autowired 
private WebApplicationContext wac; 
private MockMvc mockMvc; 

    @Autowired 
    @InjectMocks 
    private RegisterController registerController; 

    @Autowired 
    private LocalValidatorFactoryBeanMock validator; 

    @Before 
    public void setup () 
    { 
    this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); 
    // if you want to inject mocks into your controller 
      MockitoAnnotations.initMocks(this); 
    } 

    @Test 
    public void testPostValidationError () throws Exception 
    { 
     validator.fakeErrors(); 
     MockHttpServletRequestBuilder post = post("/info/register"); 
     post.param("name", "Bob"); 
     ResultActions result = getMockMvc().perform(post); 
      // no redirect as we have errors 
     result.andExpect(view().name("info/register")); 
    } 

    @Configuration 
    @Import(DispatcherServletConfig.class) 
    static class Config extends WebMvcConfigurerAdapter 
    { 
     @Override 
     public Validator getValidator () 
     { 
      return new LocalValidatorFactoryBeanMock(); 
     } 

     @Bean 
     RegisterController registerController () 
     { 
      return new RegisterController(); 
     } 
    } 
} 
3

निश्चित रूप से। ऐसा कोई कारण नहीं है कि आपका परीक्षण अपने DispatcherServlet को तुरंत चालू नहीं कर सकता है, संदर्भ कंटेनर फ़ाइल के स्थान सहित, इसमें एक कंटेनर (उदा। ServletContext) में विभिन्न आइटमों के साथ इंजेक्ट करें।

स्प्रिंग सर्वलेट से संबंधित MockXYZMockServletContext, MockHttpServletRequest और MockHttpServletResponse सहित इस उद्देश्य के लिए कक्षाएं, की एक किस्म के साथ आता है। वे सामान्य अर्थ में वास्तव में "नकली" वस्तुएं नहीं हैं, वे गूंगा स्टब्स की तरह अधिक हैं, लेकिन वे नौकरी करते हैं।

सर्वलेट के परीक्षण संदर्भ में सामान्य एमवीसी से संबंधित बीन्स होंगे, साथ ही आपके बीन्स परीक्षण के लिए होंगे। एक बार सर्वलेट प्रारंभ हो जाने के बाद, नकली अनुरोध और प्रतिक्रियाएं बनाएं, और उन्हें servet की service() विधि में फ़ीड करें। अगर अनुरोध सही तरीके से रूट हो जाता है, तो आप नकली प्रतिक्रिया के लिए लिखे गए परिणामों की जांच कर सकते हैं।

13

मैं इस तरह की चीज़ के लिए एकीकरण परीक्षण लिखता हूं। आप सत्यापन एनोटेशन के साथ एक सेम है कहते हैं:

public class MyForm { 
    @NotNull 
    private Long myNumber; 

    ... 
} 

और एक नियंत्रक कि प्रस्तुत

@Controller 
@RequestMapping("/simple-form") 
public class MyController { 
    private final static String FORM_VIEW = null; 

    @RequestMapping(method = RequestMethod.POST) 
    public String processFormSubmission(@Valid MyForm myForm, 
      BindingResult result) { 
     if (result.hasErrors()) { 
      return FORM_VIEW; 
     } 
     // process the form 
     return "success-view"; 
    } 
} 

संभालती है और आप परीक्षण करने के लिए है कि @Valid और @NotNull एनोटेशन सही ढंग से तार कर रहे हैं:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration({"file:web/WEB-INF/application-context.xml", 
    "file:web/WEB-INF/dispatcher-servlet.xml"}) 
public class MyControllerIntegrationTest { 

    @Inject 
    private ApplicationContext applicationContext; 

    private MockHttpServletRequest request; 
    private MockHttpServletResponse response; 
    private HandlerAdapter handlerAdapter; 

    @Before 
    public void setUp() throws Exception { 
     this.request = new MockHttpServletRequest(); 
     this.response = new MockHttpServletResponse(); 

     this.handlerAdapter = applicationContext.getBean(HandlerAdapter.class); 
    } 

    ModelAndView handle(HttpServletRequest request, HttpServletResponse response) 
      throws Exception { 
     final HandlerMapping handlerMapping = applicationContext.getBean(HandlerMapping.class); 
     final HandlerExecutionChain handler = handlerMapping.getHandler(request); 
     assertNotNull("No handler found for request, check you request mapping", handler); 

     final Object controller = handler.getHandler(); 
     // if you want to override any injected attributes do it here 

     final HandlerInterceptor[] interceptors = 
      handlerMapping.getHandler(request).getInterceptors(); 
     for (HandlerInterceptor interceptor : interceptors) { 
      final boolean carryOn = interceptor.preHandle(request, response, controller); 
      if (!carryOn) { 
       return null; 
      } 
     } 

     final ModelAndView mav = handlerAdapter.handle(request, response, controller); 
     return mav; 
    } 

    @Test 
    public void testProcessFormSubmission() throws Exception { 
     request.setMethod("POST"); 
     request.setRequestURI("/simple-form"); 
     request.setParameter("myNumber", ""); 

     final ModelAndView mav = handle(request, response); 
     // test we're returned back to the form 
     assertViewName(mav, "simple-form"); 
     // make assertions on the errors 
     final BindingResult errors = assertAndReturnModelAttributeOfType(mav, 
       "org.springframework.validation.BindingResult.myForm", 
       BindingResult.class); 
     assertEquals(1, errors.getErrorCount()); 
     assertEquals("", errors.getFieldValue("myNumber"));   
    } 

integration testing Spring's MVC annotations

+0

यह friggin 'भयानक है। यह वही चीज है जिसे मैं ढूंढ रहा था! धन्यवाद! –

संबंधित मुद्दे