• SpringBoot测试实践


    前言

    SpringBoot提供了一组方便使用的工具注解帮助开发人员测试应用。主要包括了以下两个模块

    • spring-boot-test
    • spring-boot-test-autoconfigure

    实践中直接使用spring-boot-starter-test则可以全部包含上述模块,同时还附赠JUnit、AssertJ、Hamcrest等工具库。

    一、应用介绍

    示例程序是一个简单的Springboot工程,工程中定义了UserController,该controller中使用了UserService。

    @RestController
    @RequestMapping("/user")
    public class UserController {
    
        @Autowired
        private UserService userService;
    
        @GetMapping("get-by-id/{id}")
        public User getUserById(@PathVariable("id") Long id) {
            User userById = userService.getUserById(id);
            return userById;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    @Component
    public class UserService {
    
        public User getUserById(Long id) {
            //模拟返回user数据
            User user = new User();
            user.setId(id);
            user.setName("wanger");
    
            return user;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    二、一般测试

    此时测试,也是用的最多

    package com.zte.sdn.oscp;
    
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.util.Assert;
    
    import com.zte.sdn.oscp.contorl.User;
    import com.zte.sdn.oscp.contorl.UserController;
    
    @SpringBootTest
    public class UserControlTest {
    
        @Autowired
        private UserController userControl;
    
        @Test
        public void testGetById() {
            User userById = userControl.getUserById(1L);
            Assert.notNull(userById, "user id not be null");
            Assert.isTrue(userById.getId() == 1L, "user id not equals 1");
            Assert.isTrue(userById.getName().equalsIgnoreCase("wanger"), "user name not equals wanger");
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    三、不启动Server进行测试

    在Spring中当存在rest接口需要进行测试,但在不启动web容器前提下测试。
    可以使用McokMvc的方法进行,如下:

    package com.zte.sdn.oscp;
    
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.autoconfigure.json.AutoConfigureJsonTesters;
    import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.boot.test.json.JacksonTester;
    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 org.springframework.util.Assert;
    
    import com.zte.sdn.oscp.contorl.User;
    
    @SpringBootTest
    @AutoConfigureMockMvc
    @AutoConfigureJsonTesters
    public class UserControllerWithMockMvcTest {
        @Autowired
        private JacksonTester<User> json;
        @Test
        void exampleTest(@Autowired MockMvc mvc) throws Exception {
            MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.get("/user/get-by-id/{id}", 1L))
                    .andExpect(MockMvcResultMatchers.status().isOk())
    //                .andDo(MockMvcResultHandlers.print())
                    .andExpect(MockMvcResultMatchers.jsonPath("$.id").value(1L))
                    .andExpect(MockMvcResultMatchers.jsonPath("$.name").value("wanger"))
                    .andReturn();
            String contentAsString = mvcResult.getResponse().getContentAsString();
            User user = json.parseObject(contentAsString);
            Assert.state(user.getId() == 1L, "id must be 1");
            Assert.state(user.getName().equalsIgnoreCase("wanger"), "name must be wanger");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    四、启动Server进行测试

    启动内嵌的Server

    package com.zte.sdn.oscp;
    
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.boot.test.web.client.TestRestTemplate;
    import org.springframework.util.Assert;
    
    import com.zte.sdn.oscp.contorl.User;
    
    
    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
    public class UserControllerWithEmbedServerTest {
    
        @Autowired
        private TestRestTemplate restTemplate;
    
        @Test
        public void exampleTest() {
            User user = this.restTemplate.getForObject("/user/get-by-id/{id}", User.class, 1L);
            Assert.notNull(user, "user can not be null.");
            Assert.isTrue(user.getId() == 1L, "user id not equals 1");
            Assert.isTrue(user.getName().equalsIgnoreCase("wanger"), "user name not equals wanger");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    五、仅测控制器层

    @WebMvcTest只会扫描您定义的控制器和MVC基础设施,因此,如果您的控制器对服务层中的其他bean有一定的依赖性,那么在您自己加载该配置或为其提供模拟之前,测试将不会启动。这个速度要快得多,因为我们只加载你应用的一小部分。

    package com.zte.sdn.oscp;
    
    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
    
    import org.junit.jupiter.api.Test;
    import org.mockito.Mockito;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
    import org.springframework.boot.test.mock.mockito.MockBean;
    import org.springframework.test.web.servlet.MockMvc;
    import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
    
    import com.zte.sdn.oscp.contorl.User;
    import com.zte.sdn.oscp.service.UserService;
    
    @WebMvcTest
    //@Import(UserService.class)
    public class UserControllerWithWebMvcTest {
    
        @Autowired
        private MockMvc mockMvc;
    
        /**
         * 使用WebMvnTest不会扫描注入
         * 也可以使用@Import注入需要的Bean
         */
        @MockBean
        private UserService userService;
    
        @Test
        public void exampleTest() throws Exception {
            User user = new User();
            user.setId(1L);
            user.setName("wanger");
            Mockito.when(this.userService.getUserById(1L)).thenReturn(user);
            this.mockMvc.perform(get("/user/get-by-id/{id}", 1L))
                    .andExpect(status().isOk())
                    .andExpect(MockMvcResultMatchers.jsonPath("$.id").value(1L))
                    .andExpect(MockMvcResultMatchers.jsonPath("$.name").value("wanger"));
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    @WebMvcTest注解内可以指定相关的Bean,测试启动也只会加载其指定的Bean,如下:

    package com.zte.sdn.oscp;
    
    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
    
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
    import org.springframework.test.web.servlet.MockMvc;
    import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
    
    import com.zte.sdn.oscp.contorl.User;
    import com.zte.sdn.oscp.contorl.UserController;
    import com.zte.sdn.oscp.service.UserService;
    
    @WebMvcTest({UserController.class, UserService.class})
    public class UserControllerWithWebMvc2Test {
    
        @Autowired
        private MockMvc mockMvc;
    
        @Test
        public void exampleTest() throws Exception {
            User user = new User();
            user.setId(1L);
            user.setName("wanger");
            this.mockMvc.perform(get("/user/get-by-id/{id}", 1L))
                    .andExpect(status().isOk())
                    .andExpect(MockMvcResultMatchers.jsonPath("$.id").value(1L))
                    .andExpect(MockMvcResultMatchers.jsonPath("$.name").value("wanger"));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
  • 相关阅读:
    【python源码解析】深入 Pandas BlockManager 的数据结构和初始化过程
    MySQL - 触发器
    IDEA一键启动多个微服务
    Flutter macOS 教程之 03 编写你的第一个macos应用程序 (教程含源码)
    阿里云国际站:互联网云巨头增速放缓 SaaS生态决胜未来?
    每日练习------使用Java实现输出如下图形。(三角形,空心菱形等)
    ASEMI肖特基二极管MBR20100CT参数,MBR20100CT大小
    Anaconda默认安装在C:\Users\xxx\.conda\envs中
    flutter_学习记录_02底部 Tab 切换保持页面状态的几种方法
    神经网络 01(介绍)
  • 原文地址:https://blog.csdn.net/sunquan291/article/details/115556047