14. 单元测试

与传统的 Java EE 开发相比,依赖注入应该使 code 对容器的依赖性降低。构成 application 的 POJO 应该可以在 JUnit 或 TestNG 测试中测试,只需使用new operator 实例化 objects,而不使用 Spring 或任何其他容器。您可以使用mock objects(与其他有价值的测试技术结合使用)来单独测试您的 code。如果您遵循 Spring 的 architecture 建议,那么代码库的干净分层和组件化将有助于更轻松地进行单元测试。例如,您可以通过存根或 mocking DAO 或 Repository 接口来测试服务层 objects,而无需在 running 单元测试时访问持久数据。

True 单元测试通常非常快速地运行,因为没有要设置的运行时基础结构。强调 true 单元测试作为开发方法的一部分将提高您的工作效率。您可能不需要测试章节的这一部分来帮助您为 IoC-based applications 编写有效的单元测试。但是,对于某些单元测试场景,Spring Framework 提供以下 mock objects 和测试支持 classes。

14.1 Mock Objects

14.1.1 环境

org.springframework.mock.env包包含EnvironmentPropertySource抽象的 mock implementations(参见第 7.13.1 节,“ Bean definition profiles”第 7.13.2 节,“PropertySource 抽象”)。 MockEnvironmentMockPropertySource对于 code 开发 out-of-container 测试很有用,因为 code 取决于 environment-specific properties。

14.1.2 JNDI

org.springframework.mock.jndi包中包含 JNDI SPI 的 implementation,您可以使用它为测试套件或 stand-alone applications 设置简单的 JNDI 环境。例如,如果 JDBC DataSources 绑定到 test code 中与 Java EE 容器中相同的 JNDI 名称,则可以在测试方案中重复使用 application code 和 configuration 而无需修改。

14.1.3 Servlet API

org.springframework.mock.web包中包含一组全面的 Servlet API mock objects,可用于测试 web 上下文,控制器和过滤器。这些 mock objects 的目标是与 Spring 的 Web MVC framework 一起使用,并且通常比动态 mock objects(如EasyMock)或其他 Servlet API mock objects(如MockObjects)更方便使用。从 Spring Framework 4.0 开始,org.springframework.mock.web包中的模拟集基于 Servlet 3.0 API。

有关 Spring MVC 和 REST Controller的完整 integration 测试以及 Spring MVC 的WebApplicationContext configuration,请参阅Spring MVC Test Framework

14.1.4 Portlet API

org.springframework.mock.web.portlet包中包含一组 Portlet API mock objects,旨在与 Spring 的 Portlet MVC framework 一起使用。

14.2 单元测试支持 Classes

14.2.1 一般测试实用程序

org.springframework.test.util包中包含几个用于单元和 integration 测试的通用实用程序。

ReflectionTestUtils是 reflection-based 实用程序方法的集合。开发人员在测试需要更改常量的 value,设置非public字段,调用非public setter 方法,或在测试涉及使用的 application code 时调用非public configuration 或生命周期回调方法时使用这些方法例如以下情况。

  • ORM 框架,如 JPA 和 Hibernate,它们容忍privateprotected字段访问,而不是域实体中 properties 的public setter 方法。

  • Spring 支持,@Inject@Resource等注释,它为privateprotected字段,setter 方法和 configuration 方法提供依赖注入。

  • 使用_an和@PreDestroy这样的 annotations 进行生命周期回调方法。

AopTestUtils是 AOP-related 实用程序方法的集合。这些方法可用于获取隐藏在一个或多个 Spring 代理后面的基础目标 object 的 reference。例如,如果您使用_Mibrary(如 EasyMock 或 Mockito)将 bean 配置为动态 mock 并且 mock 包含在 Spring 代理中,则可能需要直接访问 order 中的基础 mock 以配置对它的期望并执行验证。对于 Spring 的核心 AOP 实用程序,请参阅AopUtilsAopProxyUtils

14.2.2 Spring MVC

org.springframework.test.web包中包含ModelAndViewAssert,您可以将其与 JUnit,TestNG 或任何其他测试 framework 结合使用,以进行处理 Spring MVC ModelAndView objects 的单元测试。

要将 Spring MVC Controller单元测试为 POJO,请在 Spring 的Servlet API 模拟中使用ModelAndViewAssertMockHttpServletRequestMockHttpSession等组合。要对 Spring MVC 和 REST Controller进行彻底的 integration 测试以及 Spring MVC 的WebApplicationContext configuration,请使用Spring MVC Test Framework代替。