大家好,我是双越老师,也是 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 包裹住目标组件。
这个外层的 provider 组件需要传入 message 和 locale ,如下图
模拟 DOM 事件
可以使用 @testing-library/react
中的 fireEvent
模拟 DOM 事件 testing-library.com/docs/dom-te…
例如 click 事件,change 事件修改 input value,甚至可以模拟选择文件
还可以使用 waitFor
处理异步 testing-library.com/docs/dom-te…
Mock 全局变量
使用 Vitest 的 vi.stubGlobal
可以模拟全局变量和 API vitest.dev/api/vi.html…
使用 vi.fn()
可以模拟函数,这个也很常见。
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 }
代码如下图
使用 Zustand
当 React 组件中用到了 Zustand store 全局变量时,需要先初始化这些数据,然后才能渲染出正确的 DOM 结构。
代码如下图,在 beforeAll
或 beforeEach
钩子函数中,直接使用 setState
初始化即可。
兼容 Nextjs Router
当某些组件内部用到 useRouter()
时,例如
这个组件在测试的时候,非常简单的测试代码,就在 useRouter()
地方报错了
此时我们需要安装 next-router-mock
来 Mock router
npm install next-router-mock
然后新建一个 vitestSetup.ts 文件来配置,要考虑 next/router
还要考虑 i18n 路由 @/i18n/routing
最后
把单元测试配置到了 GitHub action 流程中,每次提交代码都自动执行代码测试,保障代码质量。
最后,前端转全栈,欢迎围观我开发的 划水AI 项目,复杂业务,真实上线,持续维护。