Loading
 
What's Next: View All Tutorial →

Spring MVC + Junit Test + Mockito Framework + Rest API Test + Unit and Integration with Dependency Injection

In this article you will learn how to do unit test with Mockito framework This program fetch the user detail based on the user type, employee or clerk The Unit test and the Integration test is handled in this application Step 1: Add required d...

Published Date: 15/02/2015  Last Modified Date: 15/02/2015    New Post



In this article you will learn how to do unit test with Mockito framework


This program fetch the user detail based on the user type, employee or clerk
The Unit test and the Integration test is handled in this application

Step 1: Add required dependency

 
    <dependencies>
        
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>
             
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.1.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.1.4.RELEASE</version>
        </dependency>
        
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
            <version>1.9.13</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.5.1</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.5.1</version>
        </dependency>
        
               
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test-mvc</artifactId>
            <version>1.0.0.M2</version>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <artifactId>spring-context</artifactId>
                    <groupId>org.springframework</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>spring-webmvc</artifactId>
                    <groupId>org.springframework</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>spring-test</artifactId>
                    <groupId>org.springframework</groupId>
                </exclusion>
            </exclusions>
        </dependency>
               
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.1.4.RELEASE</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>1.10.19</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest-all</artifactId>
            <version>1.3</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path</artifactId>
            <version>1.2.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path-assert</artifactId>
            <version>1.2.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>       
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>   
        </dependency>
        
    </dependencies>



java.servlet-api  - The servlet api jar need to be added to implement spring MVC program

Step 2. Overview of all class 


UserController.java
package com.tutorial.web;

import com.tutorial.service.UserService;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class UserController {

    @Autowired
    public UserService userService;

    @RequestMapping("/getEmployeeDetails")
    public String getUser(ModelMap map, HttpServletRequest request) {

        map.addAttribute("user", userService.getEmployeeDetails());

        return "userdetail";
    }

    @RequestMapping("/getEmployeeDetails1")
    public String getUser() {
        return "userdetail";
    }

    @RequestMapping("/getMapObject")
    public @ResponseBody
    Map getMapObject() {

        Map map = new HashMap();
        map.put("UserName", "Usha");
        map.put("Gender", "Female");
        return map;
    }

    @RequestMapping("/getInfo/{userType}")
    public @ResponseBody
    Map getUser(@PathVariable String userType) {

        Map resultMap = new HashMap();

        if ("employee".equals(userType)) {
            resultMap.put("data", userService.getEmployeeDetails());
        } else if ("clerk".equals(userType)) {
            resultMap.put("data", userService.getClerkDetails());
        } else {
            resultMap.put("data", "No record found");
        }
        return resultMap;
    }

}
UserService.java
package com.tutorial.service;

import com.tutorial.domain.User;

public interface UserService {

    public User getEmployeeDetails();

    public User getClerkDetails();
}
UserServiceImpl.java
 
package com.tutorial.serviceImpl;

import com.tutorial.domain.User;
import com.tutorial.service.UserService;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {

    
    @Override
    public User getEmployeeDetails() {
        User user = new User();
        user.setAgeGroup("24");
        user.setGender("F");
        user.setUserName("Usha");
        return user;
    }

    @Override
    public User getClerkDetails() {
        User user = new User();
        user.setAgeGroup("30");
        user.setGender("F");
        user.setUserName("Mala");
        return user;
    }

}

User.java
package com.tutorial.domain;

public class User {

    private String userName;
    private String gender;
    private String ageGroup;

/**
Generate getter & setter
*/
}



Step 3: To do unit test the controller file
 
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.tutorial.web;

import com.tutorial.domain.User;
import com.tutorial.service.UserService;
import java.util.HashMap;
import java.util.Map;
import org.junit.After;
import org.junit.AfterClass;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.util.ReflectionTestUtils;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:test-servlet.xml"})
public class UserControllerTest {

    private UserService userServiceMock;

    private UserController userController;

    public UserControllerTest() {
    }

    @BeforeClass
    public static void setUpClass() {
    }

    @AfterClass
    public static void tearDownClass() {
    }

    @Before
    public void setUp() {
        userController = new UserController();

        userServiceMock = mock(UserService.class);
        ReflectionTestUtils.setField(userController, "userService", userServiceMock);
    }

    @After
    public void tearDown() {

    }

    /**
     * Test of getUser method, of class UserController.
     */
    @Test
    public void testGetInvalidUser() throws Exception {
        String userType = "";
        Map expResult = new HashMap();
        expResult.put("data", "No record found");
        Map result = userController.getUser(userType);
        verifyZeroInteractions(userServiceMock);
        assertEquals(result, expResult);
    }

    @Test
    public void testGetEmployeeUser() throws Exception {
        //http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html#3
        String userType = "employee";
        Map expResult = new HashMap();

        User user = new User();
        user.setAgeGroup("24");
        user.setGender("F");
        user.setUserName("Usha");
        expResult.put("data", user);

        when(userServiceMock.getEmployeeDetails()).thenReturn(user);
        Map result = userController.getUser(userType);

        verify(userServiceMock, times(1)).getEmployeeDetails();
        verifyNoMoreInteractions(userServiceMock);

        assertEquals(result, expResult);
    }

}
@RunWith(SpringJUnit4ClassRunner.class) - To Do Dependency injection of spring class - similiar to dispatch servlet class.

ContextConfiguration({"classpath:test-servlet.xml"}) This configuration will be loaded for the testing

ReflectionTestUtils.setField(userController, "userService", userServiceMock);  - To replace the setter method of the usercontoller class

verify(userServiceMock, times(1)).getEmployeeDetails(); - To check whether the userService.getEmployeeDetails() is called one time only

verifyZeroInteractions(userServiceMock); - To verify this object is never been called in the function body



when(userServiceMock.getEmployeeDetails().thenReturn(user); -  When is the Mockito framework, This help to bind the return value for the function. Here when userService.getEmployeeDetails() is called, It return the hardcode user object as a result



Click here  Mockito Framework Documentation for more mockito framework function utility
 

Step 4: Integration test for the controller class by calling function with the requestingMapping url


This class has two method that test the userContoller REST url using the standalone MOCKMvcBuilders

 
package com.tutorial;

import com.tutorial.domain.User;
import com.tutorial.web.UserController;
import org.junit.Test;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.server.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.server.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.server.result.MockMvcResultMatchers.view;
import org.springframework.test.web.server.setup.MockMvcBuilders;
import org.springframework.ui.ModelMap;

public class ITStandaloneUserControllerTest {

    @Test
    public void showHomePage() throws Exception {
        MockMvcBuilders.standaloneSetup(new UserController()).build()
                .perform(get("/getEmployeeDetails1"))
                .andExpect(status().isOk())
                .andExpect(view().name("userdetail"));
    }

    @Test
    public void showHomePage1() throws Exception {

        ModelMap map = mock(ModelMap.class);

        User user = new User();
        user.setAgeGroup("24");
        user.setGender("F");
        user.setUserName("Usha");

        when(map.addAttribute("user", user)).thenReturn(map);

        Object s = MockMvcBuilders.standaloneSetup(new UserController()).build()
                .perform(get("/getEmployeeDetails1"))
                .andExpect(status().isOk())
                .andExpect(view().name("userdetail"))
                .andReturn().getResponse().getContentAsString();

        System.out.println(s);
    }
}
 

Step 5: Integration test the rest API  and validating the JSON response

 
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.tutorial;

import com.tutorial.domain.User;
import java.util.HashMap;
import java.util.Map;
import static org.hamcrest.Matchers.*;
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.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(locations = {"classpath*:test-servlet.xml"})
@TestExecutionListeners(inheritListeners = false, listeners
        = {DependencyInjectionTestExecutionListener.class,
            DirtiesContextTestExecutionListener.class})
public class ITUserControllerTest {

    public ITUserControllerTest() {
    }

    @Autowired
    private WebApplicationContext wac;

    private MockMvc mockMvc;

    @Before
    public void setUp() {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
    }

    @Test
    public void getEmployeeDetails() throws Exception {

        User user = new User();
        user.setAgeGroup("24");
        user.setGender("F");
        user.setUserName("Usha");
        mockMvc.perform(get("/getEmployeeDetails"))
                .andExpect(status().isOk())
                .andExpect(view().name("userdetail"));

    }

    @Test
    public void getEmployeeUserByType() throws Exception {

        User user = new User();
        user.setAgeGroup("24");
        user.setGender("F");
        user.setUserName("Usha");

        Map m = new HashMap();
        m.put("userName", "Usha");
        m.put("gender", "F");
        m.put("ageGroup", "24");

        Map resultMap = new HashMap();
        resultMap.put("data", user);

        System.out.println(IntegrationTestUtil.convertObjectToString(resultMap));

        ResultActions s = mockMvc.perform(get("/getInfo/{userType}", "employee"))
                .andExpect(status().isOk())
                .andExpect(content().contentType("application/json;charset=UTF-8"))
                .andExpect(jsonPath("$.data", is(m)))
                .andExpect(content().string(IntegrationTestUtil.convertObjectToString(resultMap)))
                .andExpect(jsonPath("$.data.ageGroup", is("24")))
                .andExpect(jsonPath("$.data.gender", is("F")))
                .andExpect(jsonPath("$.data.userName", is("Usha")));

    }

}


1) @Test getEmployeeDetails - test the view name return "userdetail"


2) @Test getEmployeeUserByType test this

Url: http://localhost:8084/SpringMVC/getInfo/employee

Output:
{"data":{"userName":"Usha","gender":"F","ageGroup":"24"}}

 

Points to Remember


The standaloneMockMvcBuilder test uses the web.server.request
 
org.springframework.test.web.server.request.MockMvcRequestBuilders.get

The Rest API user servlet.request
org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get

Please don't create the standalone and Rest Test in the same java file, It will cause confusion and compile-time issue

Download the Project

Click here to download
Awaiting for Administrator approval





Tags: Issue and Solutions Junit Mockito Testing Framework Spring MVC

← Back to list


Related Post




×