React + Vitest 编写可测试的组件,常见问题记录

932 阅读2分钟

大家好,我是双越老师,也是 wangEditor 作者。

我正致力于开发一个 Node 全栈 AIGC 知识库 划水AI,包括 AI 写作、多人协同编辑。复杂业务,真实上线,大家可以去注册试用,围观项目研发过程。

开始

前几天我在补写 划水AI 项目的单元测试 juejin.cn/pin/7449198…

根据 Next.js testing 文档的推荐,我选择了 Vitest 作为组件单元测试的工具。Vitest 和 Jest 是同类型的工具,前者是 Vite 团队新出的工具。

兼容 i18n 国际化

划水AI 项目支持 i18n 国际化多语言,使用 next-intl 开发的,我之前的博客有记录:Next.js 最好用的 i18n 解决方案,并发布到阿里云 Serverless

在做组件单元测试时,就需要模拟 next-intl 的使用,用一个 provider 包裹住目标组件。

image.png

这个外层的 provider 组件需要传入 message 和 locale ,如下图

image.png

模拟 DOM 事件

可以使用 @testing-library/react 中的 fireEvent 模拟 DOM 事件 testing-library.com/docs/dom-te…

例如 click 事件,change 事件修改 input value,甚至可以模拟选择文件

image.png

还可以使用 waitFor 处理异步 testing-library.com/docs/dom-te…

Mock 全局变量

使用 Vitest 的 vi.stubGlobal 可以模拟全局变量和 API vitest.dev/api/vi.html…

image.png

使用 vi.fn() 可以模拟函数,这个也很常见。

image.png

Mock API 网络请求

Vitest 不能直接模拟 API 但它在文档中提供了其他的方式 vitest.dev/guide/mocki…

参考文档,我们需要先安装 msw ,具体可参考 MSW 文档 mswjs.io/docs/gettin…

npm install msw@latest --save-dev

然后,我们模拟 API /api/user 并返回 { errno: 0 } 代码如下图

image.png

使用 Zustand

当 React 组件中用到了 Zustand store 全局变量时,需要先初始化这些数据,然后才能渲染出正确的 DOM 结构。

代码如下图,在 beforeAllbeforeEach 钩子函数中,直接使用 setState 初始化即可。

image.png

兼容 Nextjs Router

当某些组件内部用到 useRouter() 时,例如

image.png

这个组件在测试的时候,非常简单的测试代码,就在 useRouter() 地方报错了

image.png

此时我们需要安装 next-router-mock 来 Mock router

npm install next-router-mock

然后新建一个 vitestSetup.ts 文件来配置,要考虑 next/router 还要考虑 i18n 路由 @/i18n/routing

image.png

最后

把单元测试配置到了 GitHub action 流程中,每次提交代码都自动执行代码测试,保障代码质量。

最后,前端转全栈,欢迎围观我开发的 划水AI 项目,复杂业务,真实上线,持续维护。