Spring-test-MVC
Testing is one of the most important parts of software development. Well organized testing helps to keep a code of application in a good state, in a working state. There are a lot of different types of test and methodologies. In this article I want to make an introduction in unit testing of applications based on Spring MVC. Don’t hope to read all about Spring MVC testing here, because it’s just a first article about unit testing.

Speak about unit testing without some application, which I’m going to test is deception. I’ll use one of my applications from the previous post, to avoid a gossip. I recommend to make a short overview of the application before you proceed read current post.
The main goal of this tutorial is to demonstrate how to configure unit tests for a Spring MVC application in annotation maner.

Preparations

The first thing which we always have to do before start any development – add of new dependencies in Maven’s pom.xml file. This case isn’t an exception.

...
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring.version}</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test-mvc</artifactId>
			<version>1.0.0.M1</version>
			<scope>test</scope>
		</dependency>
...
	<repositories>
		<repository>
			<id>spring-maven-milestone</id>
			<name>Spring Maven Milestone Repository</name>
			<url>http://maven.springframework.org/milestone</url>
		</repository>
	</repositories>
...

I have added two new dependencies:
#1 spring-test
#2 spring-test-mvc

The first one is for support for testing Spring applications with tools such as JUnit and TestNG. This artifact is generally always defined with a ‘test’ scope for the integration testing framework and unit testing stubs. The second one is for testing Spring MVC server-side and client-side RestTemplate-based code.

Pay your attention that I added a new repository. I did this because spring-test-mvc still isn’t in official maven repository.

Controller for the unit tests

In this post I’m going to write two unit tests for the most simple controller. Here is a code of the controller:

    @Controller  
    public class LinkController {  
          
        @RequestMapping(value="/")  
        public ModelAndView mainPage() {  
            return new ModelAndView("home");  
        }  
          
        @RequestMapping(value="/index")  
        public ModelAndView indexPage() {  
            return new ModelAndView("home");  
        }  
      
    }  

So as you can see the methods in the controller is trivial, they just return some JSP. The testing of the controller implies check of request status (in success case the code should be 200) and verification of the view’s name.

Writing of unit tests for Spring MVC

Here is a quote of Petri Kainulainen:

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.

I’m going to use the Web Application Context, for this purpose I need to create a class with configurations:

package com.sprhib.init;

import org.springframework.context.annotation.*;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.*;

@Configuration
@ComponentScan("com.sprhib")
@EnableWebMvc
public class BaseTestConfig {
	
	@Bean
	public UrlBasedViewResolver setupViewResolver() {
		UrlBasedViewResolver resolver = new UrlBasedViewResolver();
		resolver.setPrefix("/WEB-INF/pages/");
		resolver.setSuffix(".jsp");
		resolver.setViewClass(JstlView.class);
		return resolver;
	}

}

And finally the class with the tests:

package com.sprhib.test;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import com.sprhib.init.BaseTestConfig;

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes=BaseTestConfig.class)
public class LinkControllerTest {
	
	@Autowired
	private WebApplicationContext wac;

	private MockMvc mockMvc;
	
	@Before
	public void init() {
		mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
	}
	
	@Test
	public void testHomePage() throws Exception {
		mockMvc.perform(get("/"))
			.andExpect(status().isOk())
			.andExpect(view().name("home"));
	}
	
	@Test
	public void testIndexPage() throws Exception {
		mockMvc.perform(get("/index.html"))
			.andExpect(status().isOk())
			.andExpect(view().name("home"));
	}
	
}

Notice that I have used static imports they provide usage of such methods as get(), status() etc. @WebAppConfiguration is a class-level annotation that is used to declare that the ApplicationContext loaded for an integration test should be a WebApplicationContext.

Look at the project structure after I have added all testing stuff:

Spring-test-MVC

Check the project on GitHub.

I hope everything is clear. Spring test MVC project is a good tool for the testing of the appropriate applications. There’s just one cons lack of documentation and tutorials. In the next tutorials I’m going to develop this theme.

About The Author

Mathematician, programmer, wrestler, last action hero... Java / Scala architect, trainer, entrepreneur, author of this blog

Close