This article mainly introduces the creation of unit tests in Spring Boot, respectively explains the Service layer unit test, Controller layer unit test based on MockMvc.
Quick navigation
- Adding Maven dependencies
- Quickly create test classes with the IntelliJ IDEA editor
- Service unit Testing
- Controller unit Test
- The problem summary
Adding Maven dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
Copy the code
Creating a test class
For Spring Boot unit tests, you can manually create test classes in the/SRC /test/ Java directory. Alternatively, you can use the IDE to quickly create test classes by clicking on the header menu of the file where the tests are to be created and selecting /Navigate/ test or T (Mac).
After clicking Test, a small popup prompts you to Create New Test… , as follows:
Click Create New Test… The following window is displayed
Click OK to create the test class userSercivetest.java
package com.angelo.service;
import static org.junit.Assert.*;
public class UserServiceTest {}Copy the code
Service unit Testing
Create a service/UserServiceTest. Java classes, in the name of the class with the following two notes, can make a normal class into a unit test class.
@RunWith(SpringRunner.class)
:@RunWith
It’s a runner,SpringRunner.class
Said the use ofSpring Test
Conduct unit tests whereSpringRunner
A derived classSpringJUnit4ClassRunner
.@SpringBootTest
: Will start the entire Spring Boot project
service/UserServiceTest.java
package com.angelo.service;
import com.angelo.aspect.HttpAspect;
import com.angelo.domain.User;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceTest {
@Autowired
private UserService userService;
private final static Logger logger = LoggerFactory.getLogger(HttpAspect.class);
@Test
public void findByIdTest(a) {
User user = userService.findById(1);
// assert whether it is as expected
Assert.assertEquals("Zhang", user.getName());
Assert.assertEquals(new Integer(-1), user.getAge()); }}Copy the code
Right-click on the test class and select Run ‘UserServiceTest’. You can see that we expected user.getage () to be 18, but actually returned -1
Controller unit Test
The above is for the business layer test, if you want to do the interface API test, is it possible to complete the development of each call postman test one by one? The answer is of course no, but you can test it one by one, and that’s fine. If you want to simulate HTTP requests in code, you use our @AutoConfiguRemockMVC annotation. With MockMvc, you don’t need to start your project to do interface testing.
The MockMvc method used is described below
mockMvc.perform
: Execute requestMockMvcRequestBuilders.get
: Supports post, PUT, and DELETEcontentType(MediaType.APPLICATION_JSON_UTF8)
: Requests transmissionConent-Type=application/json; charset=utf-8
- Accept (MediaType.APPLICATION_JSON)) : what the client wants to receive
Conent-Type=application/json;
andExpect(MockMvcResultMatchers.status().isOk())
: Returns whether the response status is the expected 200, and throws an exception if it is notandReturn()
: Returns the result
controller/UserControllerTest.java
package com.angelo.controller;
import com.angelo.domain.User;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.context.junit4.SpringRunner;
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.MockMvcResultMatchers;
import static org.junit.Assert.*;
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class UserControllerTest {
@Autowired
private MockMvc mockMvc;
/** * Query the user list *@throws Exception
*/
@Test
public void userListTest(a) throws Exception {
String url = "/user/list/false"; MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get(url)) .andExpect(MockMvcResultMatchers.status().isOk()) .andReturn(); MockHttpServletResponse response = mvcResult.getResponse(); System.out.println(response.getStatus());// Get the response status code
System.out.println(response.getContentAsString()); // Get the response content
}
/** * Create test user *@throws Exception
*/
@Test
public void userAddTest(a) throws Exception {
User user = new User();
user.setName("Test Name");
user.setAge(22);
Gson gson = new GsonBuilder().setPrettyPrinting().create();
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/user")
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content(gson.toJson(user))
.accept(MediaType.APPLICATION_JSON))
.andReturn();
MockHttpServletResponse response = mvcResult.getResponse();
System.out.println(response.getStatus()); // Get the response status code
System.out.println(response.getContentAsString()); // Get the response content
}
/** * Delete user test * by id@throws Exception
*/
public void deleteUserByIdTest(a) throws Exception {
Integer id = 11;
mockMvc.perform(MockMvcRequestBuilders.delete("/user/"+ id)) .andExpect(MockMvcResultMatchers.status().isOk()); }}Copy the code
The running result is as follows. You can see the test method and time involved in this test on the left, and the information of creating user logs and deleting user logs is printed on the console on the right. The delete user does not exist because id=11, so an exception is thrown.
The problem summary
org.hibernate.LazyInitializationException: could not initialize proxy [com.angelo.domain.User#1] - no Session
The reason is lazy loading, because Hibernate mechanism is that when we query an object, by default, only the ordinary properties of the object are returned, when the user to use the object properties, the database will be queried again, but at this time, the session has been closed, the database can not be queried.
Solution: SpringBoot configuration file Settings spring. Jpa. Properties. Hibernate. Enable_lazy_load_no_trans = true
application.yml
spring:
jpa:
hibernate:
ddl-auto: update
show-sql: true
database: mysql
properties:
hibernate:
enable_lazy_load_no_trans: true
Copy the code
Github see the full example chapter5-1 for this article
Author: you may link: www.imooc.com/article/264… Github: Spring Boot