使用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的检测方式介绍

相关推荐
千穹凌帝几秒前
SpinalHDL之结构(二)
开发语言·前端·fpga开发
dot.Net安全矩阵11 分钟前
.NET内网实战:通过命令行解密Web.config
前端·学习·安全·web安全·矩阵·.net
Hellc00722 分钟前
MacOS升级ruby版本
前端·macos·ruby
前端西瓜哥31 分钟前
贝塞尔曲线算法:求贝塞尔曲线和直线的交点
前端·算法
又写了一天BUG32 分钟前
npm install安装缓慢及npm更换源
前端·npm·node.js
cc蒲公英1 小时前
Vue2+vue-office/excel 实现在线加载Excel文件预览
前端·vue.js·excel
Java开发追求者1 小时前
在CSS中换行word-break: break-word和 word-break: break-all区别
前端·css·word
好名字08211 小时前
monorepo基础搭建教程(从0到1 pnpm+monorepo+vue)
前端·javascript
pink大呲花1 小时前
css鼠标常用样式
前端·css·计算机外设
Flying_Fish_roe1 小时前
浏览器的内存回收机制&监控内存泄漏
java·前端·ecmascript·es6