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.

  1. @RunWith(SpringRunner.class):@RunWithIt’s a runner,SpringRunner.classSaid the use ofSpring TestConduct unit tests whereSpringRunnerA derived classSpringJUnit4ClassRunner.
  2. @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 request
  • MockMvcRequestBuilders.get: Supports post, PUT, and DELETE
  • contentType(MediaType.APPLICATION_JSON_UTF8): Requests transmissionConent-Type=application/json; charset=utf-8
  • Accept (MediaType.APPLICATION_JSON)) : what the client wants to receiveConent-Type=application/json;
  • andExpect(MockMvcResultMatchers.status().isOk()): Returns whether the response status is the expected 200, and throws an exception if it is not
  • andReturn(): 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