Alexey Zvolinskiy

About Alexey Zvolinskiy

Alexey is a test developer with solid experience in automation of web-applications using Java, TestNG and Selenium. He is so much into QA that even after work he provides training courses for junior QA engineers.

Spring MVC: Introduction in testing

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. #1 spring-test
  2. #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:

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.
 

Reference: Spring MVC: Introduction in testing from our JCG partner Alexey Zvolinskiy at the Fruzenshtein’s notes blog.
Related Whitepaper:

Introduction to Web Applications Development

Kick start your web apps development with this introductory ebook!

This 376 page eBook 'Introduction to Web Applications Development', starts with an introduction to the internet, including a brief history of the TCT/IP protocol and World Wide Web. It defines the basic concepts for web servers and studies the case of Apache, the most used webserver, while other free software webservers are not forgotten. It continues with webpage design focusing on HTML and JavaScript. XML Schemas, their validation and transformation are covered as well as dynamic webpages built with CGI, PHP or JSP and database access.

Get it Now!  

5 Responses to "Spring MVC: Introduction in testing"

  1. Nice article Alexey. I have a few things to add. First of all I do not understand why do you need both spring-test and spring-test-mvc? This is only needed when you have older spring versions and this should be mentioned explicitly. There is a list of things which you CAN and which you cannot do with standalone context – otherwise Rossen would give us only one opportunity. And finally it will be good to have some examples how to mock a service layer in a controllers.

    • Alex Fruzenshtein says:

      Thanks for the comment

      1. As specified in the documentation, spring-test is required for
      testing Spring applications with tools such as JUnit and TestNG. Even
      more, I use static imports in the LinkControllerTest, they are from the
      spring-test dependency.

      2. Regarding testing of a service layer, I will write some articles about it soon.

      • I did not mean the service layer tests. The controller usually depends on some of your services. How in this case you plan to deal with that? That would make an example full.

        • FruzNotes says:

          Usually yes, almost all controllers depend on some service. But in my case I just made the introduction in testing. In the following articles I will extend the application, new tests will use some mock frameworks

  2. i’m ready for the next series :D

Leave a Reply


× 2 = six



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books