How Spring MVC Tests Controller (Using Spring MVC mock Tests)

Keywords: Java Spring Junit JSON JDBC

In spring mvc, the common test cases are the test service layer. Today I will show how to use spring MVC mock to test the controller layer code directly.  

1. What is mock testing?

mock testing is a test method that is created with a virtual object for testing some objects that are not easy to construct or acquire.

2. Why use mock testing?

Testing with Mock Object is mainly used to simulate tools that are not easy to construct in applications (e.g. HttpServletRequest must be constructed in a Servlet container) or more complex objects (e.g. ResultSet objects in JDBC) to make the test run smoothly.

3. Common Notes

RunWith (Spring JUnit4ClassRunner. class): Represents unit testing using Spring Test components;

WebAppConfiguratio n: Using this annotation will actually start a web service while running the unit test, then start calling the Rest API of Controller, and then stop the web service after the unit test runs out.

ContextConfiguration: There are many ways to specify Bean's configuration file information. This example uses the form of file path. If there are multiple configuration files, the information in parentheses can be configured as an array of strings to represent it.

4. Installing Test Environment
Sprmvc testing framework provides two ways to install and integrate Web environment testing independently (this way does not integrate the real web environment, but through the corresponding Mock API for simulation testing, without starting the server).

  • Independent Installation Test Method

MockMvcBuilders. standalone Setup (Object... controllers): Specify a set of controllers by parameters so that you don't need to get them from the context;

There are two main steps:
(1) First of all, create the corresponding controller and inject the corresponding dependencies.
(2) MockMvc Builders. standalone Setup is used to simulate an Mvc test environment, and a MockMvc is obtained by build ing.

The code is as follows:

package com.xfs.test;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xfs.web.controller.APIController;

/**
 * Spring MVC mock test with independent installation test mode
 *
 * @author admin
 *
 * 2017 November 23, 2001, 10:39:49 a.m.
 */
public class TestApiOne {

    private MockMvc mockMvc;

    @Before
    public void setUp() {
        APIController apiController = new APIController();
        mockMvc = MockMvcBuilders.standaloneSetup(apiController).build();
    }

    @Test
    public void testGetSequence() {
        try {
            MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/api/getSequence"))
                                .andExpect(MockMvcResultMatchers.status().is(200))
                                .andDo(MockMvcResultHandlers.print())
                                .andReturn();
            int status = mvcResult.getResponse().getStatus();
            System.out.println("Request status code:" + status);
            String result = mvcResult.getResponse().getContentAsString();
            System.out.println("Interface returns results:" + result);
            JSONObject resultObj = JSON.parseObject(result);
            // Judging interface return json in success Whether the field is true
            Assert.assertTrue(resultObj.getBooleanValue("success"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

 

 

The results of the request are as follows:

 

 

 

  • Integrated Web Environment Approach

MockMvcBuilders.webAppContext Setup (Web Application Context context): Specify the Web Application Context, from which the corresponding controller will be obtained and the corresponding MockMvc will be obtained.

There are three main steps:

(1)@WebAppConfiguration: Test environment usage, which indicates that the Application Context used by the test environment will be of type Web Application Context; value specifies the root of the web application
(2) Through @Autowired Web Application Context wac: Application Context container injected into the web environment
(3) Then create a MockMvc through MockMvcBuilders.webAppContextSetup(wac).build() for testing.

The code is as follows:

package com.xfs.test;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

/**
 * Spring MVC mock test with integrated Web environment
 *
 * @author admin
 *
 * 2017 November 23, 2001, 11:12:43 a.m.
 */
@RunWith(JUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(locations = { "classpath*:spring/*.xml" })
public class TestApiTwo extends AbstractJUnit4SpringContextTests {

    @Autowired
    public WebApplicationContext wac;

    public MockMvc mockMvc;

    public MockHttpSession session;

    @Before
    public void before() throws Exception {
        mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
    }

    @Test
    public void testGetSequence() {
        try {
            MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/api/getSequence"))
                                .andExpect(MockMvcResultMatchers.status().is(200))
                                .andDo(MockMvcResultHandlers.print())
                                .andReturn();
            int status = mvcResult.getResponse().getStatus();
            System.out.println("Request status code:" + status);
            String result = mvcResult.getResponse().getContentAsString();
            System.out.println("Interface returns results:" + result);
            JSONObject resultObj = JSON.parseObject(result);
            // Judging interface return json in success Whether the field is true
            Assert.assertTrue(resultObj.getBooleanValue("success"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

The results are the same as those of the above independent tests.

Conclusion:

Throughout the process:
1. MockMvc. performance executes a request;
2. MockMvcRequestBuilders.get("/user/1") Constructs a request
3. ResultActions. and Expect adds assertions after execution is complete
4. ResultActions.andDo adds a result processor to indicate what to do with the result, such as using MockMvcResultHandlers.print() here to output the entire response result information.
5. ResultActions. and Return indicate that the corresponding results are returned after the execution is completed.

The whole testing process is very regular:
1. Preparing test environment
2. Executing requests through MockMvc
3. Adding validation assertions
4. Adding Result Processor
5. Get MvcResult for custom assertions / Asynchronous requests for the next step
6. Unloading Test Environment

 

Reference:

https://docs.spring.io/spring/docs/4.0.0.RELEASE/spring-framework-reference/htmlsingle/#spring-mvc-test-framework

Posted by focus310 on Sat, 05 Jan 2019 10:18:10 -0800