RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Simplify Unit Testing for Spring Web Components : Page 3

Utilize Spring mock objects and Spring's extensions to the JUnit framework to simplify unit testing for Spring Web components.


Running Transaction "Wired" Unit Tests

So far, you've seen relatively simplistic JUnit tests that occur in the context of one controller supplied with only mock objects. But what if testing a Web component makes sense only in a transactional context (e.g., integrated with Hibernate through the dependency injection)? Spring MVC offers a decent set of extensions to the JUnit framework that do exactly that: provide injections of dependencies and transaction-safe testing (i.e., any updates are rolled back after the test completes the execution).

Testing Steps
Let's look at a hypothetical scenario in which you would implement a test for a component (e.g., MyTransactionalController) that runs in a transactional context (i.e., the results of its method invocation are within a transaction and it should be rolled back after the test runs):
  1. Create a custom JUnit class (MyTransactionalControllerTest) that extends the Spring's JUnit extension AbstractTransactionalSpringContextTests public class:
    import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
     * @author begolie
    public class MyTransactualControllerTest extends
    		AbstractTransactionalSpringContextTests {
    public class.

  2. In order to make Spring-managed beans visible to the Spring-aware unit test, you need to override the getConfigLocations() method and return the String array of context file locations, as follows:
    protected abstract  String[] getConfigLocations(){
            return new String[] {"classpath:/test/spring-context.xml"};

  3. Have a property for the classes under test, as well as associated getters and setters, because AbstractTransactionalSpringContextTests utilizes auto-wiring (a feature of the Spring framework where class dependencies are recognized by the names of the class properties and filled in with the Spring beans with the matching name or ID--See the Related Resources section for more info) and it will automatically resolve the dependencies to the classes under test as long as the class properties are named the same as the Spring-managed beans in the Spring context file and a properly named setter exists for each property under test:
    	public MyTransactualController myTransactualController;
    	 * @return Returns the myTransactualController.
    	public MyTransactualController getMyTransactualController() {
    		return this.myTransactualController;
    	 * @param myTransactualController The myTransactualController to set.
    	public void setMyTransactualController(
    			MyTransactualController myTransactualController) {
    		this.myTransactualController = myTransactualController;

  4. Implement the test method as you usually would with the "plain" JUnit tests:
    	public void testCorrectBehavior() throws Exception{
    		//run the transactional method
    		myTransactualController.submitPayment( new Payment( 100 ) ); 
    		assertTrue( myTransactualController.isValid() );

    Notice that you are calling the method submitPayment, which may update the database. Spring's JUnit extension (AbstractTransactionalSpringContextTests) will perform the automatic rollback upon the completion of this test method.

  5. If you need to perform any setup or cleanup tasks, override the AbstractTransactionalSpringContextTests's onSetUpBeforeTransaction() or onSetUpInTransaction() methods. AbstractTransactionalSpringContextTests overrides the inherited setUp() and tearDown() methods from TestCase and makes them final.

Effective Unit Testing

Now that you've learned how, go ahead and start working with the Spring unit testing frameworks and Web component mock objects. Not only will you be more productive, but your software will benefit from some effective unit testing techniques as well.

Edmon Begoli a software architect with 14 years of professional experience on large commercial and federal software projects. He is a member of the R&D staff at Oak Ridge National Laboratory.
Email AuthorEmail Author
Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date