سؤال

واجهت مشكلة في اليوم الآخر حيث تمت إزالة تعليق توضيحي Valid بطريق الخطأ من فئة وحدة تحكم. لسوء الحظ ، لم يكسر أي من اختباراتنا. لم يمارس أي من اختبارات وحدتنا بالفعل الربيع AnnotationMethodHandlerAdapter مسار. نحن فقط اختبار فصول وحدة التحكم لدينا مباشرة.

كيف يمكنني كتابة وحدة أو اختبار تكامل سيفشل بشكل صحيح إذا كانت التعليقات التوضيحية لـ MVC خاطئة؟ هل هناك طريقة يمكنني من خلالها أن أطلب من الربيع العثور على وحدة التحكم ذات الصلة وممارسة مراقبة Mockhttpservlet أو شيء من هذا القبيل؟

هل كانت مفيدة؟

المحلول

في الربيع القادم 3.2 (لقطة متوفرة) أو مع SPRING-Test-MVC (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();
        }
    }
}

نصائح أخرى

أكتب اختبارات التكامل لهذا النوع من الأشياء. قل أن لديك فول مع تعليقات التحقق من الصحة:

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"));        
    }

انظر منشور مدونتي اختبار التكامل التعليقات التوضيحية MVC الربيع

بالتأكيد. لا يوجد سبب يمنع الاختبار الخاص بك DispatcherServlet, ، حقنها بالعناصر المختلفة التي سيكون لها في حاوية (على سبيل المثال ServletContext) ، بما في ذلك موقع ملف تعريف السياق.

الربيع يأتي مع مجموعة متنوعة من servlet MockXYZ فصول لهذا الغرض ، بما في ذلك MockServletContext, MockHttpServletRequest و MockHttpServletResponse. إنها ليست حقًا كائنات "وهمية" بالمعنى المعتاد ، فهي أشبه بأعمدة غبية ، لكنهم يقومون بالمهمة.

سيحتوي سياق اختبار Servlet على الفاصوليا المعتادة المتعلقة بـ MVC ، بالإضافة إلى الفاصوليا للاختبار. بمجرد تهيئة servlet ، قم بإنشاء طلبات وردود وهمية ، وإطعامها في Servet service() طريقة. إذا تم توجيه الطلب بشكل صحيح ، فيمكنك التحقق من النتائج كما هو مكتوب على استجابة وهمية.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top