Integration Testing of Spring MVC Applications: Configuration

No one of us can deny the importance of integration testing. It is an important tool which we can use to verify that our components are working together in a correct way. However, the integration testing of web applications build by using Spring MVC has been problematic.

We have been using tools like Selenium or JWebUnit for writing integration tests against the user interface of the tested application and to be honest, it has not been a match made in heaven. This approach has three major flaws:

  • Writing and maintaining our tests takes a lot of work if our user interface in under development.
  • These tools are not very good for testing sites that uses Javascript (and especially Ajax).
  • These tests must be run against a running servlet container which is cumbersome and makes these tests slow.

The reality is that tests written by using these tools are too often abandoned because maintaining these tests takes a lot of time and often the developers feel that it just is not worth it. It is clear that we have a problem. Luckily, there is a new kid on the block called spring-test-mvc that aims to simplify the testing of Spring MVC applications.

This blog entry is the first part of my spring-test-mvc tutorial and it describes how we can configure spring-test-mvc, and implement a custom JUnit rule that makes it possible to configure the used application context by using annotations. The dependencies of this tutorial are following:

  • Spring Framework 3.1.2
  • spring-test-mvc 1.0.0.M2
  • JUnit 4.10
  • Maven 3.0.3

Lets move on and find out how we can start using spring-test-mvc in our integration tests.

Getting the Required Dependencies

Before we can use spring-test-mvc, we have to make some changes to our pom.xml file. To be more specific, we have to:

  1. Add the Spring milestone repository to the pom.xml file.
  2. Declare the spring-test-mvc dependency in the pom.xml file.

These steps are described with more details in following subsections.

Adding the Spring Milestone Repository

We can configure the Spring milestone repository by adding the following snippet to the pom.xml file:

<repositories>
	<repository>
		<id>spring-milestone</id>
		<name>Spring Portfolio Milestone Repository</name>
		<url>http://repo.springsource.org/milestone/</url>
	</repository>
</repositories>

Declaring the spring-test-mvc Dependency

We can use spring-test-mvc after we have added the following snippet to our pom.xml file:

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-test-mvc</artifactId>
	<version>1.0.0.M2</version>
	<scope>test</scope>
</dependency>

Configuring spring-test-mvc

The heart of the spring-test-mvc is a class called MockMvc that can be used to write tests for any application implemented by using Spring MVC. Our goal is to create a new MockMvc object by using the implementations of the MockMvcBuilder interface. The MockMvcBuilders class has four static methods which we can use to obtain an implementation of the MockMvcBuilder interface. These methods are described in following:

  • ContextMockMvcBuilder annotationConfigSetup(Class... configClasses) method must be used when we are using Java configuration for configuring the application context of our application.
  • ContextMockMvcBuilder xmlConfigSetup(String... configLocations) must be used when the application context of our application is configured by using XML configuration files.
  • StandaloneMockMvcBuilder standaloneSetup(Object... controllers) must be used when we want to configure the tested controller and the required MVC components manually.
  • InitializedContextMockMvcBuilder webApplicationContextSetup(WebApplicationContext context) must be used when we have already created a fully initialized WebApplicationContext object.

These configuration methods are described in the following.

Using XML Configuration

If the name of our application context configuration file is applicationContext.xml and it is found from the classpath, we can create a new MockMvc object by using the following code:

MockMvc mockMvc = MockMvcBuilders.xmlConfigSetup("classpath:applicationContext.xml").build();

Using Java Configuration

If the name of our application context configuration class is ExampleApplicationContext, we can create a new MockMvc object by using the following code:

MockMvc mockMvc = MockMvcBuilders.annotationConfigSetup(ExampleApplicationContext.class).build();

Using Standalone Configuration

If the name of our controller class is HomeController, we can create a new MockMvc object by using the following code:

MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new HomeController()).build();

Using Web Application Context

After we have obtained a fully initialized WebApplicationContext, we can create a new MockMvc object by using the following code:

WebApplicationContext wac = …
MockMvc mockMvc = MockMvcBuilders.webApplicationContextSetup(wac).build();

Configuring Our Integration Tests

We should configure our integration tests by using the web application context based configuration for two reasons:

  • The Spring MVC Test framework does not support application context based configuration. Using the web application context based configuration means that it is a lot easier to migrate our application to Spring Framework 3.2.
  • If we want to write integration tests for an application that uses Spring Security, we must use a fully initialized web application context for creating the used MockMvc objects.

Lets move on and take a look at required utility classes and learn how we can configure our integration tests.

Required Utility Classes

The spring-test-mvc samples contain two utility classes which are needed when we are writing integration tests for an application which uses Spring Framework 3.1. These classes are described with more details in the following:

  • The GenericWebContextLoader is a class that provides a support for creating WebApplicationContext objects.
  • The WebContextLoader class is an application specific extension to the GenericWebContextLoader class, and it provides us access to the WebApplicationContext of our application.

Putting It All Together

We can configure our integration tests by following these steps:

  1. Use the @RunWith annotation to configure the used test runner. In this case we must use the SpringJUnit4ClassRunner class to run our integration tests.
  2. Use the @ContextConfiguration annotation to configure either the application context configuration class or the xml configuration file. Set the value of its loader property to WebContextLoader.class.
  3. Add WebApplicationContext field to our test class and annotate it with the @Resource annotation. This field contains a reference to the used web application context.
  4. Add a MockMvc field to our test class. This field contains a reference to the MockMvc object that is used in our integration tests.
  5. Create a public setUp() method and annotate this method with the @Before annotation. This method creates a new MockMvc object by using the static webApplicationContextSetup() method of the MockMvcBuilders class.

The source code of our integration test skeleton class looks as follows:

import org.junit.Before;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.server.MockMvc;
import org.springframework.test.web.server.samples.context.WebContextLoader;
import org.springframework.test.web.server.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import javax.annotation.Resource;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = WebContextLoader.class, classes = {ExampleApplicationContext.class})
//@ContextConfiguration(loader = WebContextLoader.class, locations = {"classpath:exampleApplicationContext.xml"})
public class ITTest {

    @Resource
    private WebApplicationContext webApplicationContext;

    private MockMvc mockMvc;

    @Before
    public void setUp() {
        mockMvc = MockMvcBuilders.webApplicationContextSetup(webApplicationContext).build();
    }

    //Add tests here
}

The example application of this blog entry has two test classes that demonstrates the concepts described in this blog entry. As always, the example application is available at Github. The build process of the example application is described in my blog entry called Integration Testing with Maven.

Conclusion

We have now learned how we can configure our integration tests. This tutorial has taught us three things:

  • We are aware of different configuration options which we can use for configuring our integration tests.
  • We know that we should the use the web application based configuration because it provides us a smoother migration path to Spring Framework 3.2 and it is required if we want to write integration tests for an application which uses Spring Security.
  • We learned to create a WebApplicationContext object and inject it into our test class.

That's all folks! The next part of this tutorial describes how we can write integration tests for our controllers.

If you want to save time by writing less test code, take a look at my upcoming Test With Spring Course.
14 comments… add one
  • Rossen Stoyanchev Oct 16, 2012 @ 23:54

    Hi, thanks for taking a closer look at the Spring MVC Test library, which is now also in the master branch of the Spring Framework. One of the changes, is we've removed the annotationConfigSetup and xmlConfigSetup options in favor of the WebApplicationContext support added to spring-test in 3.2 (a.k.a @WebAppConfiguration). Here is an example test.

    • Petri Oct 17, 2012 @ 10:11

      Hi Rossen,

      That looks awesome. I will definitely address these changes in a separate blog entry after I have written the remaining parts of this tutorial.

  • Mladen Nov 10, 2012 @ 19:49

    Rossen's link is dead

    • Petri Nov 10, 2012 @ 22:17

      Thank you for telling me about this. I updated the link and it should work now.

  • Alexey Zvolinskiy Apr 23, 2013 @ 11:16

    Petri, thanks for this series of tutorials they are good enough. In the future I'm going to write a post where I will show all this stuff in action on a real Spring MVC project

  • Stephane Jun 3, 2013 @ 20:59

    I wonder how to define the WebApplicationContext in a Java class configuration.

  • Nick Jun 12, 2014 @ 13:00

    Hi, great post. I was wondering about one thing: the WebContextLoader class, is not present in the 1.0.0.M2 version at http://repo.springsource.org/milestone/ did you copy this locally to make this run? Reason that I am asking is that i can't use the 3.2 @WebAppConfiguration as we need to use 3.1...

    • Petri Jun 12, 2014 @ 13:04

      You are right. I had to copy some classes to my example application so that I could run the tests. You can get these classes from Github.

  • oniram Dec 15, 2016 @ 14:40

    Thanks! It's helped me with creating test in a legacy project!

    • Petri Dec 15, 2016 @ 21:40

      You are welcome!

Leave a Reply