Unit testing of the SPRINGMVC controller layer

Source: Internet
Author: User

Getting Ready

Test the relevant Maven dependency as follows:

<Dependency>        <groupId>Org.springframework</groupId>        <Artifactid>Spring-test</Artifactid>        <version>4.0.3.RELEASE</version>        <Scope>Test</Scope>    </Dependency>        <Dependency>        <groupId>Org.mockito</groupId>        <Artifactid>Mockito-all</Artifactid>        <version>1.9.5</version>        <Scope>Test</Scope>    </Dependency>        <Dependency>        <groupId>Junit</groupId>        <Artifactid>Junit</Artifactid>        <version>4.11</version>        <Scope>Test</Scope>    </Dependency>      <Dependency>           <groupId>Org.hamcrest</groupId>           <Artifactid>Hamcrest-core</Artifactid>           <version>1.3</version>           <Scope>Test</Scope>       </Dependency>

Some dependencies on the spring project (Spring-context, Spring-web, SPRING-WEBMVC, Spring-beans) are not listed here.

Examplereference Class

The Controller is as follows:

@Controller @requestmapping ("/") public class Democontroller {    @Autowired    private Testprojectservice Testprojectservice;    @RequestMapping (value = "Jsoncompare", method = Requestmethod.post)    @ResponseBody public    list< Fieldcomparisonfailure> Jsoncompare (@RequestParam ("expect") string expect, @RequestParam ("actual") string actual, Modelmap model,            HttpSession session) {        list<fieldcomparisonfailure> List = Testprojectservice.compare ( expect, actual);        return list;    }}

The Fieldcomparisonfailure class is as follows

/** * Models a failure when comparing. */public class Fieldcomparisonfailure {    private final String field;    Private final Object expected;    Private final Object actual;    Public fieldcomparisonfailure (String field, object expected, object actual) {        This.field = field;        this.expected = expected;        This.actual = actual;    }    Public String GetField () {        return field;    }    Public Object getexpected () {        return expected;    }    Public Object getactual () {        return actual;    }}

The Testprojectservice interface is as follows:

Public interface Testprojectservice {public    list<fieldcomparisonfailure> compare (string expect, string Actual);}

Testprojectserviceimpl specific implementation is to compare two JSON strings to return a list

@Servicepublic class Testprojectserviceimpl implements Testprojectservice {        @Override public    list< Fieldcomparisonfailure> Compare (string expect, string actual) {                Comparator Comparator = new Comparator ();        list<fieldcomparisonfailure> list = new arraylist<fieldcomparisonfailure> ();                try {            list = Comparator.compare (expect, Actual),        } catch (Jsonexception e) {            e.printstacktrace ();        }        return list;    }}

# #转载注明出处: http://www.cnblogs.com/wade-xu/p/4311657.html

Unit Test

First, consider a separate unit test, which uses Mockito to simulate the service layer to isolate the controller's test.

Package Com.wadeshop.controller;import static Org.mockito.mockito.when;import static org.mockito.Mockito.times; Import static Org.mockito.mockito.verify;import static Org.mockito.mockito.verifynomoreinteractions;import static Org.springframework.test.web.servlet.request.mockmvcrequestbuilders.post;import Static Org.springframework.test.web.servlet.result.mockmvcresulthandlers.print;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.content;import Static Org.hamcrest.matchers.hassize;import Org.junit.before;import Org.junit.test;import Org.mockito.InjectMocks;import Org.mockito.mock;import Org.mockito.mockitoannotations;import Org.springframework.http.mediatype;import Org.springframework.test.web.servlet.mockmvc;import org.springframework.test.web.servlet.setup.MockMvcBuilders; Import CoM.google.common.collect.immutablelist;import Com.wadeshop.service.testprojectservice;import Com.wadeshop.entity.fieldcomparisonfailure;public class Democontrollertest_mock {@Mock private Testprojectservi        CE testprojectservice;     @InjectMocks private Democontroller Democontroller;     Private MOCKMVC Mockmvc;                @Before public void Setup () {//Initialize mock object mockitoannotations.initmocks (this);     Setup Spring Test in standalone mode THIS.MOCKMVC = Mockmvcbuilders.standalonesetup (Democontroller). build (); } @Test public void Test () throws Exception {//prepare test data Fieldcomparisonfailu        Re e1 = new Fieldcomparisonfailure ("Number", "3", "4");                Fieldcomparisonfailure e2 = new Fieldcomparisonfailure ("number", "1", "2");        Actually parameter haven ' t use, service was mocked String expect = "";                String actual = ""; Sets a return value to be Returned when the method was called when (Testprojectservice.compare (expect, Actual)). Thenreturn (Immutablelist.of (E1                , e2));                     Construct HTTP request and expect response This.mockmvc. Perform (Post ("/jsoncompare")               . Accept (Mediatype.application_json). param ("actual", Actual). param ("expect", expect))               . Anddo (print ())//print request and response to Console. Andexpect (Status (). IsOk ())               . Andexpect (Content (). ContentType ("Application/json;charset=utf-8")). Andexpect (JsonPath ("$", Hassize (2))) . Andexpect (JsonPath ("$[0].field"). Value ("number")). Andexpect (JsonPath ("$[0].expected"). Value ("3 "). Andexpect (JsonPath (" $[0].actual "). Value (" 4 ")). Andexpect (JsonPath (" $[1].field "). Value (" Nu Mber ")). Andexpect (JsonPath (" $[1].expected "). Value (" 1 ")). Andexpect (JsonPath (" $[1].actual "). VA LUE ("2"));         Verify Interactions with any mock verify (Testprojectservice, times (1)). Compare (expect, actual);    Verifynomoreinteractions (Testprojectservice); }}

@Mock: Objects that need to be Mock

@InjectMocks: The object that needs to be injected into the mock object, here is the controller

Before test

Initializes a mock object, simulates an MVC test environment by Mockmvcbuilders.standalonesetup, injects a controller, builds a MOCKMVC, and then tests it with some of Mockmvc's APIs.

This is not a real spring MVC environment, and if you want to simulate a real environment you need to use Mockmvcbuilders.webappcontextsetup (Webapplicationcontext). Build (), see below.

Test methods need to build test data, mock service call method, return a immutablelist (google-collections Google's collection Library)

Then constructs the HTTP request and passes in the parameter execution, finally asserts verifies the expected result, regarding JsonPath's use please refer http://goessner.net/articles/JsonPath/

Run

Anddo (print ()) Prints the information to the console as follows

Mockhttpservletrequest:         HTTP Method = POST         Request URI =/jsoncompare          Parameters = {actual=[], expect=[]}< C3/>headers = {Accept=[application/json]}             Handler:                Type = Com.wadeshop.controller.DemoController               Async : Was   async started = false        async result = null  resolved Exception:                Type = null        modelandview:           View name = null                View = null               Model = null            flashmap:mockhttpservletresponse:              Status = $       Error message = null             Headers = {Content-type=[application/json;charset=utf-8]}        Content Type = Application/json;charset=utf-8                Body = [{"Field": "Number", "actual": "4", "Expected": "3"},{"field": "Number", "actual": "2", "expected": "1"}]       Forwarded URL = null      redirected URL = null             cookie = []

# #转载注明出处: http://www.cnblogs.com/wade-xu/p/4311657.html

Integration Testing

Then look at the integrated Web environment approach, which still uses spring MVC Test but needs to load Webapplicationcontext

Import static Org.hamcrest.matchers.hassize;import static Org.springframework.test.web.servlet.request.mockmvcrequestbuilders.post;import Static Org.springframework.test.web.servlet.result.mockmvcresulthandlers.print;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 Org.junit.Before;import Org.junit.test;import Org.junit.runner.runwith;import org.springframework.beans.factory.annotation.Autowired; Import Org.springframework.http.mediatype;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; @RunWith (springjunit4classrunner.class) @WebAppConfiguration (value = "src/ Main/webapp ") @ContextConfiguration (" File:src/main/resources/applicationcontext.xml ") public class    democontrollertest {@Autowired private webapplicationcontext WAC;    Private MOCKMVC Mockmvc;    @Before public void SetUp () {MOCKMVC = Mockmvcbuilders.webappcontextsetup (WAC). build (); } @Test public void Test () throws Exception {String actual = "{\" ordernumber\ ": \" 4955\ ", \" orderversion\ ": \        "1\"} ";               String expect = "{\" ordernumber\ ": \" 4956\ ", \" orderversion\ ": \" 1\ "}";               This.mockmvc. Perform (Post ("/jsoncompare"). Accept (Mediatype.application_json) . param ("actual", Actual). param ("expect", expect)). Anddo (print ()). Andexpect ( Status (). IsOk ()). Andexpect (Content (). ContentType ("Application/json")). Andexpect (JSOnpath ("$", hassize (1))). Andexpect (JsonPath ("$[0].field"). Value ("OrderNumber"). Andexpect (JS    Onpath ("$[0].actual"). Value ("4955")). Andexpect (JsonPath ("$[0].expected"). Value ("4956")); }}

@RunWith: Tell JUnit to use the Spring-test framework to allow the Web application context to be loaded.

@WebAppConfiguration: Indicates that the class uses the default root directory of the Web application to load applicationcontext, value = "Src/main/webapp" can be blank, and the default directory

@ContextConfiguration: Specify the address of the spring configuration file ("File:src/main/resources/applicationcontext.xml") that needs to be loaded

@Autowired webapplicationcontext WAC: ApplicationContext container injected into the web environment;

Use Mockmvcbuilders.webappcontextsetup (WAC). Build () to create a MOCKMVC to test, which simulates the real spring MVC environment

The test process is similar to the previous one, the only difference being that this time the actual parameter is passed and the return value is called by the real service.

Long Running time

Console information

Mockhttpservletrequest:         HTTP Method = POST         Request URI =/jsoncompare          Parameters = {actual=[{"ordernumber" : "4955", "Orderversion": "1"}], expect=[{"ordernumber": "4956", "Orderversion": "1"}]}             Headers = {accept=[ Application/json]}             Handler:                Type = Com.wadeshop.controller.DemoController               Async: Was   async started = False        Async result = null  resolved Exception:                Type = null        modelandview:           View name = null                View = null               Model = null            flashmap:mockhttpservletresponse:              Status = $       Error message = null             Headers = {Content-type=[application/json]}        Content Type = Application/json                Body = [{"Field": "OrderNumber", "Actual": "4955", "expected": "4956"}]       forwarded URL = null      redirected URL = null             cookie = []

From the above example, the integration test Spring MVC controller is not also very simple, a little configuration on the line.

# #转载注明出处: http://www.cnblogs.com/wade-xu/p/4311657.html

Summarize

The unit test process is nothing more than this trilogy:

    1. Preparation (test environment, test data)
    2. Execute (construct request incoming parameter execution)
    3. Assertion (validation result)

Troubleshooting

If some noclassdeffounderror are found, it is estimated that the dependent jar version is too old.

Import which classes do not make a mistake, some need static import, IDE tool does not necessarily prompt import

Unit testing of the SPRINGMVC controller layer

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.