8.2. 单元测试

采用依赖注射的一个主要好处是你的代码对容器的依赖将比传统J2EE开发小的多。无需Spring或任何其他容器,只要简单地通过 new 操作符即可实例化对象,通过这种方式,组成你应用的POJO对象就可以使用JUnit或TestNG进行测试了。你可以使用Mock对象(或者其他很多有价值的测试技术来进行隔离测试)。如果你的应用在架构上遵循了Spring的建议,那么你的代码将会有清晰的层次和高度的模块化,这些都将大大方便单元测试。例如,在单元测试中你可以通过stub(占位)或者mock(模仿)DAO或者Repository(库)接口的方式,来测试服务层对象,而无需访问持久化数据。

真正的单元测试运行起来通常都非常迅速,因为没有应用服务器,数据库,ORM工具等运行设施需要设置。因此在你的开发方法论中,正确对待单元测试可以大大提高你的生产力。如果你有一些基于IoC的应用,那通常并不需要专门的一章“测试”来帮助你编写有效的 单元 测试。但为了一些特定的单元测试场景,Spring框架提供了如下mock对象和测试支持类:

8.2.1. Mock对象

8.2.1.1. JNDI

org.springframework.mock.jndi 包里有一个JNDI SPI的实现,它可以用来搭建一个为测试套件或单机应用所使用的简单JNDI环境。例如,与相同的JNDI名称绑定的测试代码中的<font></font>JDBC DataSource,就像在J2EE容器中一样,应用代码和配置都可以无需修改在测试场景重用。

8.2.1.2. Servlet API

org.springframework.mock.web 包有一组Servlet API 的很详尽的mock对象,主要面向Spring Web MVC 框架,能方便的测试web上下文和控制器。这些mock对象通常比使用动态mock对象更方便(例如 EasyMock) 或已有的Servlet API mock对象(如 MockObjects).

8.2.1.3. Portlet API

org.springframework.mock.web.portlet包有一组Portlet API mock对象,面向Spring Portlet MVC框架。

8.2.2. 单元测试支持类

8.2.2.1. 通用工具类

org.springframework.test.util包内有ReflectionTestUtils。 它是基于反射的工具方法集,用在单元测试和集成测试场景中。开发者可以在测试应用代码时,设置非public 的字段或者调用非public的 setter方法,例如:

  • ORM框架如JPA和Hibernate能够使用 public Setter方法访问privateprotected字段以获得一个域实例的属性

  • Spring支持如@Autowired@Resource注解来提供privateprotected字段、setter方法和配置方法的依赖注入

8.2.2.2. Spring MVC

org.springframework.test.web包含有AbstractModelAndViewTests类,它可以作为基于JUnit 3.8的单元测试基类来处理Spring MVC ModelAndView对象。当基于Java 1.4 或更高的版本(例如与JUnit 4+, TestNG等绑定)时,你可以选择使用ModelAndViewAssert类(在相同包中)来测试 ModelAndView相关功能。

提示: 根据你的测试环境,可以扩展 AbstractModelAndViewTests或直接使用 ModelAndViewAssert,然后使用 MockHttpServletRequest, MockHttpSession等。这些类在org.springframework.mock.web 包中,用来测试Spring MVC Controller.