Test--mockito for Spring boot application
Spring boot can work with most popular test frameworks: Create unit Tests from spring JUnit, generate test data initialization database for testing, spring boot can be combined with BDD (Behavier Driven Development) tool , Cucumber, and Spock work together to test the application.
When it comes to software development, we write a lot of code, but in another six months (or even more than a year) do you know how your code works? Through testing (unit test, Integration test, interface test) can guarantee the maintainability of the system, when we modify some code, through the regression test can check whether to introduce a new bug. In a sense, the test makes the system no longer a black box, allowing the developer to confirm that the system is available.
In a Web application, there are generally two ways to test a controller layer: (1) Send an HTTP request, or (2) impersonate an HTTP request object. The first method needs to configure the regression environment to calculate coverage by modifying the policies of the Code statistics, the second method is more formal thinking, but in my current experience of the project is not used much, today summarizes how to use mock Object Test controller layer code.
In previous articles, we used the bookpub application as an example, and today is no exception, ready to test whether the RESTful interface it provides returns the correct response data. This test is different from unit testing , where the full application context needs to be initialized, all spring beans are woven, and test data is required in the database, which is generally referred to as integration testing or interface testing .
How do
An empty test file,Bookpubapplicationtest.java, is provided by Spirng.io the new Spring Boot project, with the following:
@RunWith (Springjunit4classrunner.class)
@SpringApplicationConfiguration (classes = bookpubapplication.class)
public class Bookpubapplicationtests {
@Test
public void Contextloads () {
}
}
- Add spring-boot-starter-test dependencies in the pom file, adding Jsonpath dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
</dependency>
- Adding test cases in Bookpubapplicationtest
Package com.test.bookpub;
Import Com.test.bookpub.domain.Book;
Import Com.test.bookpub.repository.BookRepository;
Import Org.junit.before;import org.junit.Test;
Import Org.junit.runner.RunWith;
Import org.springframework.beans.factory.annotation.Autowired;
Import Org.springframework.beans.factory.annotation.Value;
Import org.springframework.boot.test.SpringApplicationConfiguration;
Import Org.springframework.boot.test.TestRestTemplate;
Import Org.springframework.boot.test.WebIntegrationTest;
Import Org.springframework.http.MediaType;
Import Org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
Import ORG.SPRINGFRAMEWORK.TEST.WEB.SERVLET.MOCKMVC;
Import Org.springframework.test.web.servlet.setup.MockMvcBuilders;
Import Org.springframework.web.client.RestTemplate;
Import Org.springframework.web.context.WebApplicationContext;
Import static org.junit.Assert.assertEquals;
Import static org.junit.Assert.assertNotNull;
Import static org.hamcrest.Matchers.containsString;
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;
@RunWith (Springjunit4classrunner.class)
@SpringApplicationConfiguration (classes = bookpubapplication.class)
@WebIntegrationTest ("server.port:0")
public class Bookpubapplicationtests {
@Autowired
Private Webapplicationcontext context;
@Autowired
Private Bookrepository bookrepository;
@Value ("${local.server.port}")
private int port;
Private MOCKMVC Mockmvc;
Private Resttemplate resttemplate = new Testresttemplate ();
@Before
public void Setupmockmvc () {
MOCKMVC = Mockmvcbuilders.webappcontextsetup (context). build ();
}
@Test
public void Contextloads () {
Assertequals (1, Bookrepository.count ());
}
@Test
public void Webappbookisbnapi () {
Book book = Resttemplate.getforobject ("http://localhost:" + port + "/books/9876-5432-1111", Book.class);
Assertnotnull (book);
Assertequals ("Chinese Test", Book.getpublisher (). GetName ());
}
@Test
public void Webapppublisherapi () throws Exception {
The Mockhttpservletrequestbuilder.accept method is to set the content type that the client recognizes
Mockhttpservletrequestbuilder.contenttype, sets the Content-type field in the request header, representing the content type of the request body
Mockmvc.perform (Get ("/PUBLISHERS/1")
. Accept (Mediatype.application_json_utf8))
. Andexpect (Status (). IsOk ())
. Andexpect (Content (). String (containsstring ("Chinese Test")))
. Andexpect (JsonPath ("$.name"). Value ("Chinese test"));
}
}
- Code coverage for the Spring boot project
Using Cobertura, refer to the project's GitHub address: Spring boot template
# to-Create test coverage reports (in Target/site/cobertura)
MVN Clean Cobertura:cobertura Test
Cobertura Statistical Code Coverage
Click a class to go inside to see more information
Analysis
First, the annotations used in the bookpubapplicationtests class are analyzed:
- @RunWith (Springjunit4classrunner.class), which is a junit annotation that lets Springjunit4classrunner This class provides the spring test context.
- @SpringApplicationConfiguration (classes = Bookpubapplication.class), which is the spring boot annotation for integration testing, The spring application context needs to be loaded and configured through this annotation. This is a meta-annotation (meta-annoation), which contains the annotation @ContextConfiguration (loader = springapplicationcontextloader.class) , The test framework uses this annotation to create the application context using the Spring boot Framework's springapplicationcontextloader loader.
- @WebIntegrationTest ("server.port:0"), this annotation indicates that the current test is an integration test (integration test), so you need to initialize the full context and start the application. This annotation usually appears with the @SpringApplicationConfiguration . server.port:0 refers to having spring boot start the Tomcat service on a random port, followed by a @Value ("${local.server.port}") in the test Get the port number and assign it to the port variable. This ability to randomly acquire a port provides the parallelism of a test program when running a test program on Jenkins or other continuous integration servers.
Check out the annotations for the test class and look inside the test class. Since this is a spring boot test, we can weave any spring-managed object through the @autowired annotation, or the value of the environment variable specified by the @value setting. In the present test class, we define the webapplicationcontext and bookrepository objects.
Each test case is decorated with @test annotations. In the first Test Case--contextloads () method, I just need to confirm that the bookrepository Connection has been established and that the corresponding test data is already included in the database.
The second test case is used to test the restful url--we provide through the ISBN query for a book, "/BOOKS/{ISBN}". In this test case we use the testresttemplate object to initiate a restful request.
The third Test case shows how to implement a function similar to the second Test with the Mockmvc object. The Spring test Framework provides MOCKMVC objects that can be tested in MVC without the need for client-server requests, and can execute the controller's request completely on the server side, just as it does with the test servers.
The test environment needs to be established before the test starts, and the Setup method is @before modified. Use the mockmvcbuilders tool to create a Mockmvc object using the Webapplicationcontext object as a parameter.
The Mockmvc object provides a set of tool functions for performing assert judgments, both for Web requests. This set of tools is used as a chained invocation of functions, allowing programmers to link multiple test cases together and make multiple judgments. In this example we use some of the following tool functions:
- perform (Get (...)) Create a Web request. In our third use case, a GET request is executed through mockmvcrequestbuilder .
- andexpect (...) Can be in perform (...) Multiple calls after a function call, indicating the judgment of several conditions, the parameter type of this function is the resultmatcher interface, in mockmvcresultmatchers This class provides a lot of return the tool function for the Resultmatcher interface. This function allows you to detect multiple aspects of the same Web request, including the HTTP response status code (response status), the content type of the response (contents type), the value stored in the session, the content of the test redirect, the model or header, and so on. The response data in JSON format needs to be detected through a third-party library Json-path : Check that the JSON data contains the correct element type and corresponding values, such as JsonPath ("$.name"). Value (" Chinese test ") is used to check that there is a node named name under the root directory, and that the value for that node is" Chinese test. "
A character garbled problem
- Problem Description: Through the spring-boot-starter-data-rest established by the repository, remove the characters are garbled.
- Analysis: Using postman and Httpie verification is not a problem, it is MOCKMVC test cases are not written, you should proactively set the client how to resolve the HTTP response, using the Get.accept method to set the client-recognized content types, modified test cases are as follows:
@Test
public void Webapppublisherapi () throws Exception {
The Mockhttpservletrequestbuilder.accept method is to set the content type that the client recognizes
Mockhttpservletrequestbuilder.contenttype, sets the Content-type field in the request header, representing the content type of the request body
Mockmvc.perform (Get ("/PUBLISHERS/1")
. Accept (Mediatype.application_json_utf8))
. Andexpect (Status (). IsOk ())
. Andexpect (Content (). String (containsstring ("Chinese Test")))
. Andexpect (JsonPath ("$.name"). Value ("Chinese test"));
}
Resources
1 integration testing of RESTful APIs based on SPRING-WS
2 things to know about the Java EE-Schematic HTTP protocol
3 Integration Testing a Spring Boot application
4 Spring Boot project template
Further readings
Initializing the database and importing data-Pinterest
Transfer from Johnnie Https://yq.aliyun.com/articles/54061?spm=5176.100239.blogcont6925.8.0i1oWN
Test--mockito for Spring boot application