• SpringBoot MockMvc


    1 什么是 MockMvc?

    Spring Boot 提供了一个方便的测试工具类 MockMvc,用于对 Controller 层进行单元测试。MockMvc 提供了模拟 HTTP 请求的能力,让你可以在不启动完整的 HTTP 服务器的情况下测试 Spring MVC 控制器。

    2 为什么使用 MockMvc?

    快速:MockMvc 可以在不启动完整的应用程序服务器的情况下进行单元测试,因此测试速度更快。
    集成度高:它能够模拟 HTTP 请求和响应,以及 Spring MVC 的所有特性,如路由、过滤器、拦截器等。
    灵活性:可以对控制器的行为进行精确的模拟和验证,包括请求参数、路径变量、请求头等。

    3 如何使用 MockMvc?

    在使用 MockMvc 进行单元测试时,你需要创建一个 MockMvc 实例,并使用它来构建和执行 HTTP 请求,然后验证返回结果。

    3.1 Controller

    package com.xu.test.controller;
    
    import com.xu.test.service.TestService;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.annotation.Resource;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.util.HashMap;
    import java.util.Map;
    
    @RestController
    @RequestMapping("/test")
    public class TestController {
    
        @Resource
        private TestService testService;
    
    
        @RequestMapping("/test1")
        public String test1(String a, Integer b) {
            return testService.test1(a, b);
        }
    
        @RequestMapping("/test2")
        public Object test2(HttpServletRequest request, HttpServletResponse response, String a, Integer b) {
            testService.test2(request, response, a, b);
            Map<String, Object> body = new HashMap<>();
            body.put("a", a);
            body.put("b", b);
            return body;
        }
    
    }
    
    • 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

    3.2 测试方法一

    package com.xu.test;
    
    import cn.hutool.json.JSONUtil;
    import org.junit.Assert;
    import org.junit.Before;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.MediaType;
    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.ResultActions;
    import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
    import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
    import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
    import org.springframework.test.web.servlet.setup.MockMvcBuilders;
    import org.springframework.web.context.WebApplicationContext;
    
    import javax.servlet.http.Cookie;
    import java.util.HashMap;
    import java.util.Map;
    
    @SpringBootTest
    @RunWith(SpringRunner.class)
    public class MockMvcTest1 {
    
        private MockMvc mock;
    
        @Autowired
        private WebApplicationContext wac;
    
        @Before
        public void setUp() {
            mock = MockMvcBuilders.webAppContextSetup(wac).build();
        }
    
        @Test
        public void get() throws Exception {
            ResultActions actions = mock.perform(MockMvcRequestBuilders.get("/test/test1?a=1&b=2")
                    .header("X-Access-Token", "0123456789")
                    .cookie(new Cookie("cookie", "123456789"))
                    .param("a", "1")
                    .param("b", "2"));
    
            // 期望请求成功
            actions.andExpect(MockMvcResultMatchers.status().isOk());
            // 打印请求头
            actions.andDo(MockMvcResultHandlers.print());
    
            MvcResult result = actions.andReturn();
            // 断言
            Assert.assertTrue(result.getResponse().isCommitted());
        }
    
        @Test
        public void post() throws Exception {
            // 请求体
            Map<String, Object> body = new HashMap<>();
            body.put("a", "1");
    
            // 请求
            ResultActions actions = mock.perform(MockMvcRequestBuilders.post("/test/test2")
                    .header("X-Access-Token", "0123456789")
                    .header(HttpHeaders.AUTHORIZATION, "0123456789")
                    .content(JSONUtil.toJsonPrettyStr(body))
                    .param("a", "1")
                    .param("b", "2")
                    .contentType(MediaType.APPLICATION_JSON_VALUE));
    
            // 期望返回的是JSON
            actions.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON));
            // 期望返回的a=1
            actions.andExpect(MockMvcResultMatchers.jsonPath("$.a").value(1));
            // 期望请求成功
            actions.andExpect(MockMvcResultMatchers.status().isOk());
            // 打印请求头
            actions.andDo(MockMvcResultHandlers.print());
            // 结果
            MvcResult result = actions.andReturn();
            // 断言
            Assert.assertEquals(MediaType.APPLICATION_JSON_VALUE, result.getResponse().getContentType());
        }
    
    }
    
    
    • 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
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88

    3.3 测试方法二

    package com.xu.test;
    
    import com.xu.test.controller.TestController;
    import com.xu.test.service.TestService;
    import org.junit.Assert;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    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.context.junit4.SpringRunner;
    import org.springframework.test.web.servlet.MockMvc;
    import org.springframework.test.web.servlet.MvcResult;
    import org.springframework.test.web.servlet.ResultActions;
    import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
    import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
    import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
    
    import javax.servlet.http.Cookie;
    
    @RunWith(SpringRunner.class) // 声明使用 SpringRunner 进行测试
    @WebMvcTest(TestController.class) // 声明需要测试的 Controller 类
    public class MockMvcTest3 {
    
        @Autowired
        private MockMvc mockMvc;
    
        @MockBean
        private TestService testService;
    
        @Test
        public void test1() throws Exception {
            ResultActions actions = mockMvc.perform(MockMvcRequestBuilders.get("/test/test1")
                    .header("X-Access-Token", "0123456789")
                    .cookie(new Cookie("cookie", "123456789"))
                    .param("a", "1")
                    .param("b", "2"));
    
            // 期望请求成功
            actions.andExpect(MockMvcResultMatchers.status().isOk());
            // 打印请求头
            actions.andDo(MockMvcResultHandlers.print());
            // 结果
            MvcResult result = actions.andReturn();
            // 断言
            Assert.assertTrue(result.getResponse().isCommitted());
        }
    
    }
    
    
    • 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
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
  • 相关阅读:
    Allure进阶-动态生成报告内容
    “论大数据处理架构及其应用”写作框架,软考高级,系统架构设计师
    使用 MITRE ATT&CK 技术保护您的 Active Directory安全
    测试/开发程序员,如何跳出技术瓶颈?一年两年......
    算法竞赛进阶指南 0x65 负环与差分约数
    webpack中stylelint配置,手动校验样式方案
    面试 - react-redux开发者工具的使用
    k8s service的一些特性
    【LeetCode】【剑指offer】【数组中出现次数超出一半的数字】
    JVM 运行时数据区与JMM 内存模型详解
  • 原文地址:https://blog.csdn.net/qq_34814092/article/details/138848118