10.2 Unit testing

One of the main benefits of Dependency Injection is that your code should really depend far less on the container than in traditional J2EE development. The POJOs that make up your application should be testable in JUnit or TestNG tests, with objects simply instantiated using the new operator, without Spring or any other container. You can use mock objects (in conjunction with many other valuable testing techniques) to test your code in isolation. If you follow the architecture recommendations around Spring you will find that the resulting clean layering and componentization of your codebase will naturally facilitate easier unit testing. For example, you will be able to test service layer objects by stubbing or mocking DAO or Repository interfaces, without any need to access persistent data while running unit tests.

True unit tests typically will run extremely quickly, as there is no runtime infrastructure to set up, whether application server, database, ORM tool, or whatever. Thus emphasizing true unit tests as part of your development methodology will boost your productivity. The upshot of this is that you often do not need this section of the testing chapter to help you write effective unit tests for your IoC-based applications. For certain unit testing scenarios, however, the Spring Framework provides the following mock objects and testing support classes.

10.2.1 Mock objects

10.2.1.1 JNDI

The org.springframework.mock.jndi package contains an implementation of the JNDI SPI, which is useful for setting up a simple JNDI environment for test suites or stand-alone applications. If, for example, JDBC DataSources get bound to the same JNDI names in test code as within a J2EE container, both application code and configuration can be reused in testing scenarios without modification.

10.2.1.2 Servlet API

The org.springframework.mock.web package contains a comprehensive set of Servlet API mock objects, targeted at usage with Spring's Web MVC framework, which are useful for testing web contexts and controllers. These mock objects are generally more convenient to use than dynamic mock objects (e.g., EasyMock) or existing Servlet API mock objects (e.g., MockObjects).

10.2.1.3 Portlet API

The org.springframework.mock.web.portlet package contains a set of Portlet API mock objects, targeted at usage with Spring's Portlet MVC framework.

10.2.2 Unit testing support classes

10.2.2.1 General utilities

The org.springframework.test.util package contains ReflectionTestUtils, which is a collection of reflection-based utility methods for use in unit and integration testing scenarios in which the developer would benefit from being able to set a non-public field or invoke a non-public setter method when testing application code involving, for example:

  • ORM frameworks such as JPA and Hibernate which condone the usage of private or protected field access as opposed to public setter methods for properties in a domain entity

  • Spring's support for annotations such as @Autowired and @Resource which provides dependency injection for private or protected fields, setter methods, and configuration methods

10.2.2.2 Spring MVC

The org.springframework.test.web package contains ModelAndViewAssert, which can be used in combination with any testing framework (e.g., JUnit 4+, TestNG, etc.) for unit tests dealing with Spring MVC ModelAndView objects.

[Tip]Unit testing Spring MVC Controllers

To test your Spring MVC Controllers, use ModelAndViewAssert combined with MockHttpServletRequest, MockHttpSession, etc. from the org.springframework.mock.web package.