首页 > 其他分享 >使用@WebMvcTest--使用MockMvc框架来模拟HTTP请求进行测试--实现对单个控制器的http模拟测试

使用@WebMvcTest--使用MockMvc框架来模拟HTTP请求进行测试--实现对单个控制器的http模拟测试

时间:2023-07-19 19:55:58浏览次数:45  
标签:bookService -- springframework Book 测试 org test import 模拟

1.优点

无需启动内置服务器就可以对Controller中某一个HTTP接口进行测试,减少电脑内存占用和运行springboot时间消耗

2.控制器类简单的方法

package com.xurong.chapter4_test.controller;

import com.xurong.chapter4_test.Entity.Book;
import com.xurong.chapter4_test.repository.ReadingListRepository;
import com.xurong.chapter4_test.service.BookService;
import com.xurong.chapter4_test.service.impl.BookServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

/**
 * @author xu
 * @Description
 * @date 2023/7/19 - 9:50
 * @Modified By:
 */
@RequiredArgsConstructor
@RestController
@RequestMapping("/book")
public class BookController {

    private final BookService bookService;

    @GetMapping("/all")
    public List<Book> getAll() {
        return bookService.getAll();
    }
    @GetMapping("/{id}")
    public Book getById(@PathVariable("id") Long id) {
        return bookService.getById(id);
    }

    @PostMapping("/insert")
    public void insert(@Valid @RequestBody Book book) {
        bookService.insert(book);
    }


}

3.使用MockMvc框架来模拟HTTP请求进行测试

package com.xurong.chapter4_test.controller;

import com.xurong.chapter4_test.Entity.Book;
import com.xurong.chapter4_test.service.BookService;
import org.hamcrest.Matchers;
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.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;

import static org.hamcrest.Matchers.containsString;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;


import java.util.ArrayList;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.when;

/**
 * @author xu
 * @Description
 * @date 2023/7/19 - 16:38
 * @Modified By:
 */
@WebMvcTest(BookController.class)
class BookControllerTest {

    @MockBean
    private BookService bookService;

    @Autowired
    private MockMvc mockMvc;

    @Test
    void checkMockMvc() {
        // 检验MockMvc对象是否注入成功
        assertNotNull(mockMvc);
    }

    // 测试:@GetMapping("/all")
    @Test
    void getAll() throws Exception {
        List<Book> books = new ArrayList<>();
        // 模拟正确访问应该返回的List数据值
        Book book1 = new Book(1L, "张三", "300", "三国演义", "罗贯中", "诸葛亮,周瑜,曹操");
        Book book2 = new Book(2L, "xu", "300", "三国演义", "罗贯中", "诸葛亮,周瑜,曹操");
        books.add(book1);
        books.add(book2);

        when(bookService.getAll())
                .thenReturn(books);

        // 发送请求,对结果与上面模拟的结果值进行对比验证
        this.mockMvc.perform(get("/book/all"))
                .andDo(print())
                // 验证响应状态码为200
                .andExpect(status().isOk())
                // 检验List结果集合的大小为2
                .andExpect(jsonPath("$.size()").value(2))
                // 检验list结合中的第2个对象的reader属性值是否为“xu”
                .andExpect(jsonPath("$[1].reader").value("xu"));

    }

    // 测试:public Book getById(@PathVariable("id") Long id)
    @Test
    void getById() throws Exception {
        // 模拟正确访问应该返回的book数据值
        Book book2 = new Book(2L, "xu", "300", "三国演义", "罗贯中", "诸葛亮,周瑜,曹操");
        when(bookService.getById(2L)).thenReturn(book2);

        // 发送http请求,在请求路径上添加id值
        this.mockMvc.perform(
                MockMvcRequestBuilders.get("/book/{id}",2L))
                .andDo(print())
                .andExpect(jsonPath("$.reader").value("xu"));
    }

    // 测试:public void insert(@Valid @RequestBody Book book)
    // 对于@Valid也可以起到验证作用
    @Test
    void insert() throws Exception {
        this.mockMvc.perform(MockMvcRequestBuilders.post("/book/insert")
                .contentType(MediaType.APPLICATION_JSON)
                .content("{\"reader\":\"小武a\",\"isbn\":\"400\",\"title\":\"水浒传\",\"author\":\"施耐庵\",\"description\":\"武松:打虎英雄\"}"))
                //使用andDo(print())方法打印出请求和响应的详细信息
                .andDo(print());

        // 使用verify方法验证BookService的insert方法是否成功被调用,并且传入的参数是一个Book对象。
        // 这可以通过any(Book.class)来实现,表示任意类型的Book对象都可以作为参数传入
        verify(bookService).insert(any(Book.class));
    }
}

4.需要注意的地方

注意1:如果BookControllerTest注入了BookService,那么在编写测试方法时需要使用@MockBean注入service的对象,注意不是使用原生的@Resource,@Autowired或者构造器进行注入

 @MockBean
 private BookService bookService;

注意2:需要将模拟容器注入进来,当然注入的方法有多种,网上自行搜索

@Autowired
private MockMvc mockMvc;

注意3:这一段时发送http请求,MockMvcRequestBuilders有多个方法,也可以添加请求头和请求体等信息

this.mockMvc.perform(
MockMvcRequestBuilders.get("/book/{id}",2L))

注意4:
后面的几个方法是对http请求结果进行验证,andDo方法将测试结果打印,andExpect对http请求结果的期望值;
注意一定要调用(when(bookService.getById(2L)).thenReturn(book2);),否则("$.reader")不会起作用

    @Test
    void getById() throws Exception {
        // 创建了一个Book对象book2,并使用when方法模拟了调用bookService.getById(2L)时应该返回book2对象的情况
        Book book2 = new Book(2L, "xu", "300", "三国演义", "罗贯中", "诸葛亮,周瑜,曹操");
        when(bookService.getById(2L)).thenReturn(book2);

        // 发送http请求,在请求路径上添加id值
        this.mockMvc.perform(
                MockMvcRequestBuilders.get("/book/{id}",2L))
                .andDo(print())
                .andExpect(jsonPath("$.reader").value("xu"));
    }

参考视频:
视频up-github地址
MockMvcRequestBuilders文档地址

标签:bookService,--,springframework,Book,测试,org,test,import,模拟
From: https://www.cnblogs.com/rong-xu-drum/p/17566581.html

相关文章

  • HTTP
    一、HTTP协议概述1.概念HyperTextTransferProtocol,超文本传输协议,规定了浏览器和服务器之间数据传输的规则。2.特点(1)基于TCP协议:面向连接,安全(2)基于请求-响应模型的:一次请求对应一次相应(3)HTTP协议是无状态的协议:对于事务处理没有记忆能力。每次请求-相应都是独立的。缺......
  • Day07_1.深浅copy之浅copy
    浅拷贝原理:是把原列表第一层的内存地址不加区分的完全copy一份给新列表1.深浅copy之浅copy_1: 2.浅拷贝的id不同: 3.浅copy列表的内部元素是指向同一个的,所以单个元素的id相同: ......
  • CocosCreator + Vscode + Ts 代码注释生成文档,利用typedoc
    需求:脚本的代码注释,生成为文档基本搭建环境:(cocoscreator2.4.x+vscode+ts)、(nodejs+npm)步骤:1、安装typedoc:npminstall-gtypedoc2、项目根目录添加/创建typedoc.json文件3、然后再项目tsconfig.json文件加入(4步骤报错可选)"downlevelIteration":true4、......
  • [SUCTF 2019]EasySQL
    [SUCTF2019]EasySQL题目来源:buuctf题目类型:web涉及考点:SQL注入、堆叠注入1.题目给了一个输入框,先随便传点东西进去传入数字回显如下:传入flag回显如下:传入字符无回显没什么其他线索了,还是爆破一下看看过滤了哪些字符:返回长度为507的字符都是被过滤了的,包括uni......
  • day83(2023.7.19)
    1.使用SqlSession操作数据库 2.Mapper动态代理原理3. MyBatis新增 运行结果:4.MyBatis修改没优化前: 优化后:(只需写一次就ok了) 运行结果:4.MyBatis删除、根据Id查询 运行结果: 5.根据ID查询用户和运行结......
  • 数据结构与算法 头歌 图的拓扑排序算法
    数据结构与算法之图的拓扑排序算法导言拓扑排序是对有向无环图(DirectedAcyclicGraph,DAG)进行排序的一种算法。在实际开发中,拓扑排序算法常用于解决任务调度、编译顺序等问题。本文将介绍拓扑排序算法的实现过程,并帮助初学者理解该算法的原理及代码实现。拓扑排序流程以下......
  • 数据仓库历史数据
    数据仓库历史数据什么是数据仓库?数据仓库(DataWarehouse)是一种用于集成和存储组织中各种业务系统中生成的大规模、历史性的数据的一种关系型数据库。它是一个集中存储和管理数据的地方,用于支持决策支持和业务智能分析。数据仓库通过将分散的、异构的数据源进行抽取、转换和加载(E......
  • 数据仓库分层设计
    数据仓库分层设计引言数据仓库是一个用于集成和分析大量数据的系统,它可以帮助企业进行决策支持和业务分析。在构建一个高效的数据仓库时,合理的分层设计是非常重要的。通过将数据仓库划分为多个层次,可以提高数据的组织性、可维护性和查询性能。流程概览下面是数据仓库分层设计的......
  • 数据仓库udf
    数据仓库UDF(用户定义函数)什么是数据仓库?数据仓库(DataWarehouse)是指集成、清洗、整理和存储大量结构化和非结构化数据的系统。它是用于支持企业决策和分析的重要工具。数据仓库可以从多个源系统中提取数据,并将其转化为可理解和可用于分析的格式。数据仓库通常包含历史数据,以便进......
  • vm 因为部分网络问题ping不通虚拟机,虚拟机也上不了网的经历
    主机连着公司wifi,wifi上网需要登录认证账号,此账号同时只能在线一个,不好办一网络适配器用vmnet0,桥接到wifi网卡,能ping通了,但是总是断,ssh一小会就断。ip尝试过静态、动态都不行二适配器vmnet8网络的nat模式,ping不通,vm8网络-属性-配置里图中改成enable。不行。后来ping通了改回diabled......