sts-junit learning articles -mockMVC @RequestBody data transmission solutions

1. An example:

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Before;
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.transaction.TransactionConfiguration;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.WebApplicationContext;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
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.status;

/**
 * Created by zhengcanrui on 16/8/11.
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring/applicationContext-*xml"})

// configuration rollback transaction, additions and deletions to the database will be rolled back, to facilitate recycling test of
the @TransactionConfiguration entry in (the transactionManager = "the transactionManager", to true the defaultRollback =)
@Transactional

// The above two effects is that we will operate the database transaction rollback, such as adding operation of the database, after the end of the method, we will revoke the operation of the database // make.

// Why transaction rollback?

  • // test the operation of the database, will have dirty data, affect the accuracy of our data
  • // convenient test cycle, that is, if this time we will be a record is deleted, the next time will no longer be the Junit test, because the record has been deleted, it will be thrown.
  • // If you do not use a transaction rollback, we need explicit about our additions and deletions to the database recovery operations in the code will be a lot more testing and independent code 

@WebAppConfiguration
public the Test class {
    // remember configuration log4j.properties, command line output level is Debug
    protected Logger = LogFactory.getLog the Log (TestBase.class);

    protected MockMvc mockMvc;

    @Autowired
    protected WebApplicationContext wac;

    @Before () // This method will be executed once prior to performing each method
    public void Setup () {
        mockMvc = MockMvcBuilders.webAppContextSetup (WAC) .build (); // initialize objects MockMvc
    }

    org.junit.Test @
    public void getAllCategoryTest () throws Exception {
        String responseString = mockMvc.perform (
                GET ( "/ the Categories / getAllCategory") // URL request, the request method GET
                        .contentType (MediaType.APPLICATION_FORM_URLENCODED) // data format
 .param ( "pcode", "root ") // add parameters
        ) .andExpect (status (). isOk ()) // returns state 200 is
                .andDo (Print ()) // print-out request, and corresponding content
                .andReturn () getResponse () getContentAsString ( );.. // converts data corresponding to a string
        System.out.println ( "-------- returned json =" + responseString);
    }

}

Spring MVC test often seems more complicated. In fact, he's different is that he needs a ServletContext to simulate our requests and responses. Spring for a Spring MVC but also provides an analog test interface requests and responses in order to facilitate testing of our cell coverage is not only service, dao layer.

2, Code explanation:

@webappconfiguration is a comment for declaring a test load ApplicationContext integrated WebApplicationContext. Role is to simulate ServletContext

@ContextConfiguration: Because the controller, component and the like are used annotations, annotation specifies required spring configuration file, scanning the corresponding configuration, the class initialization.

Methods Analysis:

 

We add a send operation, add a softinfo objects, softinfo class is defined as follows:

public class SoftInfo {
    private String id;
    private String name;
}

After you have added, because we had unit testing transaction is rolled back , we will no longer be seen in our database our add operation, we can not determine whether the operation was successful .

In order to solve the above problems, we can add the json data returned in a "data" field, parse the json data fields in the data, to determine whether we are adding the operation was successful. json format is as follows:

{
    "status":200,
    "data":{"id":"2","name":"测试"}
}

We can use andExpect method of data returned by the judgment, "$ attribute" Get inside the data, as I want to get return data "data.name", can be written as "$ .data.name". The following example is to determine the return data.name = "test."

 

 

@Test
    public void testCreateSeewoAccountUser() throws Exception {
        mockMvc.perform(post("/users")
                        .contentType(MediaType.APPLICATION_FORM_URLENCODED)  
        ).andExpect(status().isOk())
        .andExpect(jsonPath("$.data.name", is("测试"))))  
        .andExpect(jsonPath("$.data.createTime", notNullValue()))
        ;
    }

3, problems encountered

 

  • Perform : performing a RequestBuilder request , automatically performs SpringMVC and mapped to a corresponding process controller executes processing;
  • get : a method of transmitting declaration of the get request. MockHttpServletRequestBuilder get (String urlTemplate, Object ... urlVariables): worth to a GET request method according to uri uri template and variable. Further provided is a request other methods, such as: post, put, delete and the like.
  • param : add request parameters, such as when sending a request to bring the above parameters in pcode = root. If you need to use the transmission data format json when used in this way it will not be visible behind the solution parameters annotated @ResponseBody
  • andExpect : Add ResultMatcher validation rules, the controller performs verified the result is correct (judgment of the returned data);
  • andDo : Add ResultHandler results of the processor, such as printing to the console (judgment of the returned data) of debugging;
  • andReturn : finally returns the corresponding MvcResult; custom authentication and / asynchronous processing of the next step (determination of the returned data);

    3, the background data is returned, it is preferable to bring the front end we return the result of modification of the database.

    Why return to a modified or added in data objects

  • Data back to the distal tip easily determine whether to add or modify data successfully
  • End update or add data often need to refresh the page, the data directly to the front-end, front-end do not have to send a request to obtain
  • When unit testing, can DDL for the database (CRUD) operations, we can review the data, where to determine whether our operations are successful. As in the following example:

1, sends a parameter is @ResponseBody identified until 400 error. I.e., not a data transmission format to the Controller json layer.

Workaround 1

SoftInfo softInfo = new SoftInfo();
//设置值
ObjectMapper mapper = new ObjectMapper();
        ObjectWriter ow = mapper.writer().withDefaultPrettyPrinter();
        java.lang.String requestJson = ow.writeValueAsString(softInfo);
        String responseString = mockMvc.perform( post("/softs").contentType(MediaType.APPLICATION_JSON).content(requestJson)).andDo(print())
                .andExpect(status().isOk()).andReturn().getResponse().getContentAsString();

Solution 2: using com.alibaba.fastjson.JSONObject data object is converted Json

SoftInfo softInfo = new SoftInfo();
//。。。设置值
String requestJson = JSONObject.toJSONString(folderInfo);
        String responseString = mockMvc.perform( post("/softs").contentType(MediaType.APPLICATION_JSON).content(requestJson)).andDo(print())
                .andExpect(status().isOk()).andReturn().getResponse().getContentAsString();

Note that the above need contentType provided MediaType.APPLICATION_JSON, i.e., the transmission data is declared "application / json" format. The method of using content, converts the data into json in body request.

2、java.lang.NoClassDefFoundError: com/jayway/jsonpath/InvalidPathException

The lack of a jar package:

You can add maven dependent on what the

<dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path</artifactId>
            <version>0.8.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path-assert</artifactId>
            <version>0.8.1</version>
            <scope>test</scope>
        </dependency>

 

Published 11 original articles · won praise 6 · views 10000 +

Guess you like

Origin blog.csdn.net/LYW_lyw/article/details/104478765