SpringBoot test (Junit unit test, MockMvc test Http request)

Summary of Java knowledge points: If you want to see it, you can enter it from here

2.13. Test

Testing is used to check whether the function of a certain piece of code can be executed correctly during the development process. When a Spring Boot project is created, the default unit testing framework spring-boot-test is used, which combines Spring Test, JUnit and other testing frameworks (JUnit 5 , AssertJ, Hamcrest, Mockito, JSONassert, JsonPath, Spring Test, and Spring Boot Test).

When using the test, you can get the support of the test directly through the starter: spring-boot-starter-test.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Some annotations are provided in SpringBoot to help us test:

  1. @SpringBootTest: Look for a main configuration class (@SpringBootApplication) and use it to start the Spring application context. SpringBootTest loads the complete application and injects all possible beans, so it takes some time.

    1. MOCK (default): loads the web ApplicationContext and provides a mock web environment, the embedded server will not start, can be used with @AutoConfigureMockMvc or @AutoConfigureWebTestClient for mock-based web application testing.
    2. RANDOM_PORT: Load a WebServerApplicationContext and provide a real web environment. The embedded server starts and listens on a random port.
    3. DEFINED_PORT: Load WebServerApplicationContext and provide a real web environment. The embedded server will start and listen on a defined port (in yml) or default port 8080.
    4. NONE: Loads the ApplicationContext by using SpringApplication, but does not provide any web environment (mock or otherwise).
  2. @Test: used to test the actual business logic on the method

  3. @AutoConfigureMockMvc: Used together with SpringBootTest, it can automatically configure MockMvc and test Controller

2.12.1, Junit unit test

1. Test

A starter for unit testing needs to be added, which will automatically import junit-related dependencies:

<!--单元测试-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
image-20230309110302564

Use the test to test the method in the project to see if its execution can achieve our expected effect, create a corresponding test class for the corresponding class, and add the annotation @Test to the method to make the test method the same as the main method It can be run directly, so that the final execution effect of the method can be observed.

We can use IDEA to directly generate a unit test class for a certain class.

  • Press ctrl+shitf+T shortcut key in the corresponding class

    image-20220924152420422 image-20220924152204998
  • Select the method to be tested, and generate the test class (the framework class for the unit test is generated, and the specific business code needs to be filled in by yourself)

    image-20220924152552459
  • Choose a select method to generate a test class

    image-20220924153708481
  • Add annotations SpringBootTest annotations (managed beans can be loaded), and write business logic

    image-20220924154713768
2. Commonly used annotations
  1. @SpringBootTest: is a combined annotation that contains the runner annotation @ExtendWith used in JUnit5

    image-20230309111010563
  2. @Test: Used on a method, indicating that the method is a test method that can be run

  3. @DisplayName("name"): Set a name for the test class

  4. enhanced processing

    1. @BeforeEach: Pre-method, which will be executed before each test method is executed
    2. @AfterEach: post-method, which will be executed after each test method is executed
    3. @BeforeAll: means to execute before all test methods
    4. @AfterAll: means to execute after all test methods
    @SpringBootTest
    @Slf4j
    class JunitTest {
          
          
        @Test
        public void test() {
          
          
            log.info("测试1");
        }
        @Test
        public void test2() {
          
          
            log.info("测试2");
        }
        @Test
        public void test3(){
          
          
            log.info("测试3");
        }
    
        @BeforeEach
        public void BeforeEach(){
          
          
            log.info("在每个方法执行前执行");
        }
        @AfterEach
        public void afterEach(){
          
          
            log.info("在每个方法执行后执行");
        }
        @BeforeAll
        static void beforeAll(){
          
          
            log.info("在所有测试方法执行前执行");
        }
        @AfterAll
        static void afterAll(){
          
          
            log.info("在所有测试方法执行后执行");
        }
    }
    
    image-20230309112331581
  5. @Disabled: Used before the test method, it can run when the method is executed alone, but if you click on the test class to run all the methods in the test class, the method with this annotation will not run

    image-20230309112559622

  6. @Timeout(value = timeout time, unit = timeout time unit): Set the execution time of the method, if it times out, an exception will occur.

    TimeUnit.DAYS: represents the time unit of twenty-four hours

    TimeUnit.HOURS: represents the time unit of sixty minutes

    TimeUnit.MINUTES: represents the time unit of sixty seconds.

    TimeUnit.SECONDS: The time unit represents one second

    TimeUnit.MILLISECONDS: Indicates the time unit of one-thousandth of a second.

    TimeUnit.MICROSECONDS: represents the time unit of one-thousandth of a millisecond

    TimeUnit.NANOSECONDS: represents the time unit of one-thousandth of a microsecond

  7. @RepeatedTest (number of times): This method will execute the specified number of times each time it runs. The @Test annotation needs to be removed

    image-20230309113407342

    image-20230309113438627

3, affirmation

Where class Assertions is a collection of utility methods that support asserting conditions in a test, unless otherwise specified, a failed assertion will throw org.opentest4j.AssertionFailedError or its subclasses. All JUnit assertions are static methods in the org.junit.jupiter.Assertions class

1、assertTrue(boolean condition):判断给定的boolean是否为true
2、assertFalse(boolean condition):判断给定的boolean是否为false
3、assertNull(Object actual):判断 Object 是否为null
4、assertNotNull(Object actual):判断 Object 不是null
5、assertEquals(o1,o2):判断两个对象是否相等
6、assertArrayEquals([][]):判断连个数组是否相等

2.12.2、MockMvc

Junit cannot test the method in the Controller because it is a network request, so we can use MockMvc to test the Controller method

MockMvc is provided by the spring-test package. MockMvc implements the simulation of Http requests. It can directly use the form of the network and convert to the call of the Controller, making the verification of the request more convenient.

There are two notes here:

  • @WebMvcTest: Using this annotation will disable full automatic configuration, only configure MVC related configuration

    image-20220925100447808
  • @AutoConfigureMockMvc: Automatically configure MockMvc

Test with @AutoConfigureMockMvc+@SpringBootTest:

  • Create a Controller normally

    @Controller
    @RequestMapping("/testMockMvc")
    public class UserinfoController {
          
          
        @Resource
        private UserinfoService userinfoService;
    
        @GetMapping("/getUserinfo")
        @ResponseBody
        public Userinfo userinfo(long id){
          
          
            return userinfoService.getById(id);
        }
    
        @GetMapping("/hello")
        public String hello(String name , Model model){
          
          
            model.addAttribute("user", name+"欢迎欢迎");
            return "hello";
        }
    }
    
  • write test class

    @SpringBootTest
    @AutoConfigureMockMvc
    public class UserControllerTest {
          
          
       
        @Autowired
        private MockMvc mockMvc;
        /*
         * 1、mockMvc.perform执行一个请求。
         * 			MockMvcRequestBuilders.get("XXX") get提交访问controller的一个接口。
         *    		MockMvcRequestBuilders.post("XXX") post提交访问controller的一个接口。
         * 			.param  传递的参数
         * 			.accept(MediaType.TEXT_HTML_VALUE))接受的响应结果的文档类型
         *    		.contentType   请求数据的文档类型
         *			.content()   可以传递JSON数据
         * 2、.andExpect  添加执行完成后的断言。
         * 3、.andDo  添加一个结果处理器,表示要对结果做点什么事情
         *   比如此处使用MockMvcResultHandlers.print()输出整个响应结果信息。
         * 7、.andReturn表示执行完成后返回相应的结果。
         */
        @Test
        public void getUserinfo() throws Exception {
          
          
            MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/testMockMvc/getUserinfo")
                            .param("id","1")
                            .contentType(MediaType.APPLICATION_JSON)
                    ).andDo(print())
                    .andExpect(status().isOk())
                    .andReturn();
    
        }
        @Test
        public void hello() throws Exception {
          
          
            MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/testMockMvc/hello")
                            .param("name","yu")
                    ).andDo(print())
                    .andExpect(status().isOk())
                    .andReturn();
    
        }
    }
    
  • Test page jump

    image-20230309143545367
  • Test return data

    image-20230309143749907

Guess you like

Origin blog.csdn.net/yuandfeng/article/details/129726212