跳到主要内容
版本:7.0.3

MockMvc 与端到端测试(End-to-End Tests)

Hunyuan 7b 中英对照 MockMvc vs End-to-End Tests

MockMvc 是基于 spring-test 模块中的 Servlet API 模拟实现构建的,它不依赖于正在运行的容器。因此,与使用实际客户端和运行中的真实服务器进行的完整端到端集成测试相比,存在一些差异。

最简单的理解方式是从一个空的MockHttpServletRequest开始。你向其中添加的任何内容,就构成了最终的请求内容。可能会让你感到意外的是:默认情况下没有上下文路径(context path);没有jsessionid cookie;没有请求转发、错误处理或异步调度功能;因此,也不会有实际的JSP渲染。相反,“转发”和“重定向”的URL会被保存在MockHttpServletResponse中,并且可以通过预期(expectations)来进行验证。

这意味着,如果你使用JSP,你可以验证请求被转发到的JSP页面,但不会渲染任何HTML。换句话说,JSP并不会被执行。不过需要注意的是,所有不依赖于请求转发的其他渲染技术(如Thymeleaf和Freemarker)会按照预期将HTML渲染到响应体中。通过@ResponseBody方法渲染JSON、XML和其他格式的数据时也是如此。

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

每种方法都有其优缺点。Spring MVC Test提供的选项涵盖了从传统的单元测试到完整的集成测试的各个阶段。可以肯定的是,Spring MVC Test中的任何选项都不属于传统单元测试的范畴,但它们与单元测试更为接近。例如,你可以通过向控制器中注入模拟的服务来隔离Web层,在这种情况下,你只是通过DispatcherServlet来测试Web层,但使用的是实际的Spring配置,就像你可以将数据访问层与上层隔离开来单独测试一样。此外,你还可以使用独立设置(standalone setup),一次专注测试一个控制器,并手动提供使其能够运行所需的配置。

在使用Spring MVC Test时,另一个重要的区别在于,从概念上讲,这类测试是服务器端测试,因此你可以检查使用了哪个处理器(handler),是否通过HandlerExceptionResolver处理了异常,模型的内容是什么,存在哪些绑定错误(binding errors)以及其他细节。这意味着编写测试预期(expectations)会更容易,因为与通过实际的HTTP客户端进行测试时不同,服务器在这里并不是一个“不透明的盒子”。这通常是经典单元测试(classic unit testing)的一个优势:编写、理解和调试这类测试更加容易,但它们并不能替代完整的集成测试(full integration tests)的必要性。同时,重要的是不要忽视这样一个事实:响应(response)是检验的核心。简而言之,即使在同一个项目中,也存在多种测试风格和策略的运用空间。