1. Preface
Most of the developers contacted in Java development do not pay much attention to testing the interface, resulting in various problems in the docking. Some also use tools such as Postman for testing, although there is no problem in the use of the interface, if the interface increases the permissions testing is more disgusting. So it is recommended to test the interface in unit testing to ensure the robustness of the interface before delivery first self-test. Today we share how Spring MVC interfaces are tested in development.
Before you start make sure you add Spring Boot Test related components, which in the latest version should contain the following dependencies.
This article was done under Spring Boot 2.3.4.RELEASE.
2. Testing the control layer alone
If we need to test only the control layer interface (Controller) and that interface does not depend on Spring beans declared with annotations like @Service
, @Component
, etc., you can enable testing only for the web control layer with the help of @WebMvcTest
, e.g.
|
|
This way is much faster and it loads only a small part of the application. But if you are involved in the service layer this way is not working and we need another way.
3. holistic testing
Most interface tests under Spring Boot are holistic and comprehensive tests that involve all aspects of the control layer, service layer, persistence layer, etc., so you need to load a more complete Spring Boot context. We can do this by declaring an abstract test base class at this point.
|
|
MockMvc
will be injected into Spring IoC only if@AutoConfigureMockMvc
is present.
Then the following test code is written for the specific control layer.
|
|
4. MockMvc Testing
When integration testing, you want to be able to test the Controller by entering the URL, if you start the server and set up the http client to test, this will make the test very troublesome, for example, slow start, test verification is not convenient, dependent on the network environment, etc., so in order to be able to test the Controller, so the introduction of MockMvc
.
MockMvc
implements the simulation of Http requests, which can directly use the form of the network, converted to Controller calls, which can make the test fast and does not depend on the network environment, and provides a set of verification tools, which can make the request verification uniform and very convenient. Next, let’s construct a test mock request step by step, assuming we have an interface like the following.
|
|
The parameter is set to name=felord.cn&age=18
, then the corresponding HTTP message will look like this.
The predictable return values are:
In fact the testing of the interface can be divided into the following steps.
Building the request
Building requests is handled by MockMvcRequestBuilders
, which provides all the request properties such as Method, Header, Body, Parameters and Session. The request for the /foo/user
interface can be converted into.
Execute the Mock request
The Mock request is then executed by MockMvc
.
Processing the results
The request results are encapsulated in the ResultActions
object, which encapsulates a variety of methods that allow us to process the results of Mock requests.
Expectation of the result
The ResultActions#andExpect(ResultMatcher matcher)
method is responsible for expecting the result of the response to see if it meets the expectations of the test. The parameter ResultMatcher
is responsible for extracting the parts of the response object that we need to expect to be compared.
If we expect the interface /foo/user
to return JSON
with an HTTP status of 200
and a response body containing the value version=v1
, we should declare this.
JsonPath is a powerful JSON parsing class library, learn about it via its project repository at https://github.com/json-path/JsonPath.
Processing of responses
The ResultActions#andDo(ResultHandler handler)
method is responsible for printing or logging output, streaming output for the entire request/response, and is provided by the MockMvcResultHandlers
tool class. We can see the details of the request response in all three ways.
For example the /foo/user
interface.
|
|
Get the return result
If you wish to further process the results of the response, you can also get the results of type MvcResult
for further processing via ResultActions#andReturn()
.
The complete testing process
Usually andExpect
is the one we will necessarily choose, while andDo
and andReturn
will be useful in some scenarios, and both of them are optional. Let’s concatenate the above.
|
|
This kind of streaming interface unit testing is also semantically better understood. You can use various assertions, positive and negative examples to test your interface and ultimately make your interface more robust.
5. Summary
Once you become proficient in this approach, you will write interfaces that are more authoritative and less flawed, and you can even sometimes use Mock to design interfaces that are more relevant to your business. So CRUD isn’t completely untechnical. High-quality and efficient CRUD often requires such engineered unit tests to support it.
Reference https://felord.cn/mockmvc.html