MockMvc与端到端测试

MockMvc是建立在spring-test模块中的Servlet API模拟实现之上,不依赖于正在运行的容器。因此,与实际客户端和运行中的服务器进行完整端到端集成测试时会有一些差异。

最简单的思考方式是从一个空的MockHttpServletRequest开始。您添加的内容就是请求的内容。可能会让您感到意外的是,默认情况下没有上下文路径;没有jsessionid cookie;没有转发、错误或异步派发;因此也没有实际的JSP渲染。相反,“转发”和“重定向”URL保存在MockHttpServletResponse中,并且可以通过期望进行断言。

这意味着,如果您使用JSP,可以验证请求被转发到的JSP页面,但不会呈现任何HTML。换句话说,JSP不会被调用。但是,请注意,所有不依赖于转发的其他渲染技术,如Thymeleaf和Freemarker,会按预期将HTML呈现到响应主体中。对于通过@ResponseBody方法呈现JSON、XML和其他格式的内容也是如此。

或者,您可以考虑使用Spring Boot中的完整端到端集成测试支持,使用@SpringBootTest。请参阅Spring Boot参考指南

每种方法都有其利弊。Spring MVC Test提供的选项是从经典单元测试到完整集成测试的不同阶段。可以肯定的是,Spring MVC Test中的选项都不属于经典单元测试范畴,但它们更接近一点。例如,您可以通过将模拟服务注入到控制器中来隔离Web层,在这种情况下,您只通过DispatcherServlet测试Web层,但使用实际的Spring配置,就像您可能会将数据访问层与其上面的层隔离进行测试一样。此外,您可以使用独立设置,一次专注于一个控制器,并手动提供所需的配置使其工作。

在使用Spring MVC Test时的另一个重要区别在于,概念上,这些测试是服务器端的,因此您可以检查使用了哪个处理程序,是否使用HandlerExceptionResolver处理了异常,模型的内容是什么,有哪些绑定错误等细节。这意味着编写期望更容易,因为服务器不像通过实际HTTP客户端进行测试时那样是一个不透明的盒子。这通常是经典单元测试的优势:更容易编写、理解和调试,但并不能取代完整集成测试的必要性。同时,重要的是不要忽视检查响应的重要性。简而言之,在同一个项目中甚至可以有多种风格和测试策略的空间。