使用Vitest api多种测试方案

API的多种测试方案

使用vitest 单元测试框架时 ,我们去解决api的测试方案一般会有多种

下面我们划分一下这三种解决方案:

这里列举了多种方案的方式,以及在使用这几种方案分别是代替了哪一层去做,从下图我们可以清晰的看到每种方案所对应的在流程中的作用

1.直接mock axios

首先,我们先看第一种使用mock axios 来处理:

这是我们的case案例,可以在todolist中去增加信息,并且可以通过remove去删除,我们可以看下下面的基本逻辑

内部实现的逻辑部分:内部所有api的调用都是放在pinia里面

updateTodoList 它直接去请求fetchTodoList,拿到数据之后,我们将其赋值给todos,也就是响应式对象,赋值后视图就自动刷新了。

addTodo 它直接去请求后端接口 fetchAddTodo ,后端接口会返回data和state。请求完后,我们去创建一个todoItem,里面存入后端返回的id和title,判断state后将其传入到todos里面。

removeTodo 它直接去请求fetchRemoveTodo,基于后端返回到数据,然后根据数据去查找对应的todo,然后再将它删除掉。

其中的api是写好了,对应实际的业务场景十分类似:

接下来就进行 mock axios

回到测试case里面,我们首先去引入axios进行mock,vi.mock("axios");然后去使用mocked.(axios.post),因为我们addtodo是一个post。看对应的注释部分代码是用了mockResolvedValue 因为它返回的是一个promise。其中要去写一个data,data中还有一个data,这部分是对应我们上面逻辑去写,对应的mock结构。

这里我们漏测了一个东西,axios的入参也是需要测试的。因为当我们去将入参删掉后,发现并不会影响到我们的测试case,不会去发现问题,直接去返回了对应的数据。

所以我们要通过行为验证,验证axios.post是不是接收到了一个title,所以在其中我们要进行一个验证,也就是代码验证部分去调用axios.post 验证是否被调用。这种方式是行为验证的方式,那么在代码中,其实使用了另一种方式:状态验证去测试,我们先补充vitest api部分。

在模拟 Axios 的 post 方法时:如果你希望模拟返回一个已解决的 Promise 对象,可以使用 mockResolvedValue。如果你需要自定义返回的 Promise 对象的实现逻辑,可以使用 mockImplementation

而去使用 mockImplementation其中返回的值是传入进来的title,所以如果不去传,那我们就会报错。那么我们也不用去验证最后axios.post,会比较灵活,也方便我们重构。

那么看第二个case就会方便很多,只需要修改一下返回数据,并且需要去准备一组数据,才能进行验证remove。所以第一次的时候我们需要是一个addtodo,第二次我们需要removetodo,这里是使用了 mockImplementationOnce,和之前的逻辑其实是一样的,这里的id也是需要用户去输入的。

第三个case也是同理,直接去做一个todoList,模拟一个后端返回一个结构。

这样去做完,虽然是可以通过case,但是我们是将外部的axios实现细节进行了暴露。如果有一天它被替代掉,那么耦合在我们测试代码里的axios都需要进行替换掉。而且我们还需要去控制它内部的输入和输出部分,所以这种方案并不是很推荐。

第二种方案 mock 中间层

我们使用这种方式在图中去展示可以发现是去做了中间层api这部分,代替了axios去模拟。

而代码部分的修改,我们之间可以去对比一下:

而其中我们可以看到它暴露的部分比之前是减少了许多,输入只接收一个title,而且返回的时候只用返回data和state,所以这就是我们去mock中间层的方案。其他的两个case可以去改写一下,而且这个方案我们去使用时候,方法我们命名是十分明显的,去做什么比之前要清晰许多。

这种mock中间层是十分去推荐的,虽然去暴露了api的实现细节,但是这些是基本稳定的。

第三种方案 msw

这种方案,mock server worker,这是mock了最后一层,发起ajax请求的时候发起拦截

pnpm i msw -D 先去安装msw

然后创建mocks文件夹,里面创建server.ts

第二步要去在测试case中去借助生命周期钩子

一开始去监听,每个case完成后要去rest,最后的话要去关闭server,这就是初始化msw的一个逻辑。最后再去写内部逻辑是跟koa 和 express是很类似的。下面是进行了一个封装使用的:

使用msw中rest,然后如何去返回值,只需要去res context.json对应的数据结构就可以了。

然后再用server.use去使用mockAddTodo,因为封装好了就方便我们多次调用

这种使用msw去实现是有一定学习成本的,如果对于koa和express熟悉的话,上手很快

初始化逻辑调整

这边最后要处理的一个点就是初始化逻辑,当我们的todo.spec脚本去执行的时候,我们先去执行setup中写好初始化,就可以不用在每一个脚本中去写。

而去写的话我们现在是使用的vite的conifg,vitest其实是可以共用viteconfig,我们可以换成vitest/config,可以解决类型报错。这里的defineConfig 继承vite,所以我们这样替换使用后不会有类型报错的问题。把原先的逻辑封装到setup.ts中配置,就可以使用了。

这样去配置好后,就可以十分清晰我们的代码逻辑。

如果团队想去使用mock server worker的方案,可以去读一下mswjs.io/ 官方文档

以上就是三种api的检测方式介绍

相关推荐
蜡台6 分钟前
Uniapp H5Builderx 预览Html 显示404问题解决
前端·uni-app
We་ct12 分钟前
LeetCode 190. 颠倒二进制位:两种解法详解
前端·算法·leetcode·typescript
踩着两条虫23 分钟前
AI驱动的Vue3应用开发平台深入探究(二十五):API与参考之Renderer API 参考
前端·javascript·vue.js·人工智能·低代码·前端框架·ai编程
信创DevOps先锋30 分钟前
本土化突围:Gitee如何重新定义企业级项目管理工具价值
前端·gitee·jquery
圣光SG42 分钟前
Java类与对象及面向对象基础核心详细笔记
java·前端·数据库
Jinuss1 小时前
源码分析之React中的useImperativeHandle
开发语言·前端·javascript
ZC跨境爬虫1 小时前
CSS核心知识点与定位实战全解析(结合Playwright爬虫案例)
前端·css·爬虫
Jinuss1 小时前
源码分析之React中的forwardRef解读
前端·javascript·react.js
mengsi551 小时前
Antigravity IDE 在浏览器上 verify 成功但本地 IDE 没反应 “开启Tun依然无济于事” —— 解决方案
前端·ide·chrome·antigravity
Можно1 小时前
pages.json 和 manifest.json 有什么作用?uni-app 核心配置文件详解
前端·小程序·uni-app