Writing Junit Tests with Spring4 Mvc

Writing Junit Tests with Spring4 Mvc thumbnail
64K
By Dhiraj 19 November, 2016

Today we will take a look into writing Junit test cases with Spring Mvc. We will be creating a sample Spring MVC app with hibernate and write few test cases using Junit and clear our concepts on writing Junit test cases with Spring Mvc.

Background

JUnit is a unit testing framework for the Java. It is mostly used in test-driven development, and is one of a family of unit testing frameworks which is collectively known as xUnit. It is always recommended to write test cases for whatever functionality a developer develops irrespective of simple applications or larger ones. The larger projects which has multiple modules and dependencies, it is not really possible to perform manual end-to-end functionality test on the go. Junit is very helpful in those scenarios. Also Junit encourages for modular programming as modular programming can be easily tested using Junit.

To start with writing Junit test cases first we need to identify what are the different units of the app we are developing. In a typical Spring MVC app, Controllers, Services, DAOs each represent a single unit. And our Junit test cases should represent these each units seperately. In those cases of course we also need Mockito fameworks to mock different units while writing test caases for a particular unit.

Here in this posts, we are intrested to write Junit test cases to test end-to-end functionality as our application will be a simple Spring MVC application. Here is the spring web application for which we will be writing the Junit test cases. Spring framework has made writing Junit test cases much simpler as it has many built-in supports to write Junit test cases for a Spring web app.

Environment Setup

1. JDK 8 2. Spring 4 3. Hibernate 4 4. Intellij Idea/ eclipse

Project Structure

spring-junit-example-project-structure

Maven Dependencies

Following are the maven dependencies which needs to be included in the pom file to start with the Junit test cases.

pom.xml
		<dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
			<version>4.1.2</version>
			<scope>test</scope>
        </dependency>
		
		<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
			<version>${spring.version}</version>
			<scope>test</scope>
		</dependency>
		
        <dependency>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest-all</artifactId>
			<version>1.3</version>
			<scope>test</scope>
		</dependency>

Java Config

Following is the configuration required to integrate Junit with Spring mvc.

TestBeanConfig
package com.developerstack.test.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@ComponentScan(basePackages = "com.developerstack")
public class TestBeanConfig {

}
 Other Interesting Posts
Spring 5 Features and Enhancements
Spring Boot Spring MVC Example
Spring Hibernate Integration with complete JavaConfig
Spring Boot Security Redirect after Login with complete JavaConfig
Spring Security Hibernate Example with complete JavaConfig
Securing REST API with Spring Security Basic Authentication
Spring Security Password Encoding using Bcrypt Encoder
Spring Security Custom Form Login Example
Spring JMS Activemq Integration with Spring Boot
Websocket spring Boot Integration without STOMP with complete JavaConfig
Maintaining Spring Session during Websocket Connection
Spring MVC Angularjs Integration with complete JavaConfig
Spring Junit Integration with complete JavaConfig
Spring Ehcache Cacheable Example with complete javaConfig
Spring Boot Thymeleaf Example

Server Side

Now let us define our controller. This controller will map the requests coming from angular service. Here we have 2 mappings to validate the user credentials and to load the user details.

UserController.java
package com.developerstack.controller;

import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.developerstack.model.UserDetails;
import com.developerstack.service.UserService;
import com.google.gson.Gson;

@Controller
public class UserController {
	
	@Autowired
	private UserService userService;
	
	@RequestMapping(value = "/validate", method = RequestMethod.POST)
	public ResponseEntity validate(@RequestBody String userString, HttpServletRequest request) {
        Map user = new Gson().fromJson(userString, Map.class);
		userService.validateUser(user, request);
		return new ResponseEntity(HttpStatus.OK);
	}
	
	@RequestMapping(value = "/details", method = RequestMethod.GET)
	public ResponseEntity> userDetails() {
        
		List userDetails = userService.getUserDetails();
		return new ResponseEntity>(userDetails, HttpStatus.OK);
	}

}

Following is the entity class. The class is annotated as hibernate entity.

UserDetails.java
package com.developerstack.model;

@Entity
@Table
public class UserDetails {
	
	@Id
	@Column
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private int id;
	@Column
	private String firstName;
	@Column
	private String lastName;
	@Column
	private String email;
	@Column
	private String password;
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	
	public String getFirstName() {
		return firstName;
	}
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}
	public String getLastName() {
		return lastName;
	}
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}

}

Let us define our service. It has simple logic to validate the user from DB and return the userdetails.

UserServiceImpl.java
package com.developerstack.service.impl;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Service;

import com.developerstack.model.UserDetails;
import com.developerstack.service.UserService;

@Service
public class UserServiceImpl implements UserService {

	@Autowired
	private UserDao userDao;

	public void validateUser(Map user, HttpServletRequest request) {
		String userName = user.get("email");
		String password = user.get("password");
		UserDetails userDetails = userDao.findUserByEmail(email);
		if(userDetails == null || !userDetails.getPassword().equals(password)) {
			throw new RuntimeException("Invalid credentials.");
		}
		return userDetails;
		}
	}

	public List getUserDetails() {
		return userDao.getUserDetails();
	}

}

Let us define the dao.

UserDaoImpl.java
package com.developerstack.dao.impl;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.developerstack.dao.UserDao;
import com.developerstack.model.UserDetails;

@Component
public class UserDaoImpl implements UserDao {
	
	@Autowired
	private SessionFactory sessionFactory;
	
	public UserDetails findUserByEmail(String email) {
		UserDetails userDetails = null;
		Criteria criteria = sessionFactory.openSession().createCriteria(UserDetails.class);
		criteria.add(Restrictions.eq("email", email));
		List entityList = criteria.list();
		if(!entityList.isEmpty()) {
			userDetails = entityList.get(0);
		}
		return userDetails;
	}

	public List getUserDetails() {
		Criteria criteria = sessionFactory.openSession().createCriteria(UserDetails.class);
		return criteria.list();
	}

}

Let us define our test class now. @WebAppConfiguration :Typically a Servlet container would provide the ServletContext but since we are in a testing environment, you need a fake servletContext and @WebAppConfiguration provides that.

UserControllerTest.java
package com.developerstack.controller;

import com.developerstack.model.UserDetails;
import com.developerstack.test.config.TestBeanConfig;
import com.google.gson.Gson;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.junit.Assert.*;

@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestBeanConfig.class})
public class UserControllerTest {
	
	@Autowired
	private UserController userController;

	@Test
	public void validateUser_Test_Positive() {
		Map params = new HashMap();
		params.put("email", "admin@admin.com");
		params.put("password","admin");
		ResponseEntity result =  userController.validate(new Gson().toJson(params));
		assertNotNull(result);
		assertEquals(result.getStatusCode(), HttpStatus.OK);
	}
	
	@Test
	public void userDetails_Test() {

		ResponseEntity> result =  userController.userDetails();
		assertNotNull(result);
		assertTrue(result.getBody().size() > 0);
	}

}

Conclusion

I hope this article served you that you were looking for. If you have anything that you want to add or share then please share it below in the comment section.

Download the source

Share

If You Appreciate This, You Can Consider:

We are thankful for your never ending support.

About The Author

author-image
A technology savvy professional with an exceptional capacity to analyze, solve problems and multi-task. Technical expertise in highly scalable distributed systems, self-healing systems, and service-oriented architecture. Technical Skills: Java/J2EE, Spring, Hibernate, Reactive Programming, Microservices, Hystrix, Rest APIs, Java 8, Kafka, Kibana, Elasticsearch, etc.

Further Reading on Spring MVC