java - 测试 Spring @MVC 注解

标签 java unit-testing spring spring-mvc spring-annotations

前几天我遇到了一个问题,@Valid 注释被意外地从 Controller 类中删除了。不幸的是,它没有破坏我们的任何测试。我们的单元测试都没有实际使用 Spring AnnotationMethodHandlerAdapter 路径。我们只是直接测试我们的 Controller 类。

如果我的@MVC 注释有误,我该如何编写单元测试或集成测试正确失败?有没有一种方法可以让 Spring 使用 MockHttpServlet 或其他东西找到并运行相关的 Controller ?

最佳答案

我为这种事情写集成测试。假设您有一个带有验证注释的 bean:

public class MyForm {
    @NotNull
    private Long myNumber;

    ...
}

和一个处理提交的 Controller

@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 上的博文

关于java - 测试 Spring @MVC 注解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2314377/

相关文章:

java - 使用 JPATest 和 MongoDB Test 为 Polyglot Springboot 编写测试

java - setTickLabelRotation(-90) 不适用于水平 CategoryAxis

Java - 下载后开始上传

java - 强制继承链的每个类覆盖抽象方法

unit-testing - 如何在 Xcode 中组织库项目的单元测试?

django - 如何使用 django-nose 运行单个测试或单个 TestCase?

java - 在java中保存一个对象数组供以后在另一个程序中使用

python - 引导测试和使用 Python 测试发现

java - Ant 匹配器结尾为

model-view-controller - javax.validation.ConstraintViolationException : Bean Validation constraint(s) violated on preUpdate validation