5月30日 01:39
如何对 Zustand store 进行单元测试?
Zustand store 单测重点是把状态恢复到干净初始值,再验证 action、异步状态和 selector 行为。同步 action 可以直接用 getState() 调;React hook 场景用 renderHook 和 act;异步 action 要 mock 请求并等待 Promise 结束。面试里别只说“很好测”,要提到全局 store 会污染用例,必须在 beforeEach 重置。
追问
为什么每个测试前要重置 store?
Zustand store 默认是模块级单例,上一个测试改过的状态会留到下一个测试,导致用例顺序一变就失败。
测 action 一定要 renderHook 吗?
不一定。纯 store 逻辑用 useStore.getState().action() 更快;只有要验证 hook 订阅和组件重渲染时,才需要 renderHook。
异步 action 怎么测?
mock fetch 或请求层,调用 action 后断言 loading、data、error 的最终状态。需要中间态时,可以分阶段 await。
selector 性能怎么测?
订阅一个具体 selector,更新无关字段,断言渲染次数不变;再更新目标字段,断言它才重新触发。
写段代码
javascriptbeforeEach(() => { useStore.setState({ count: 0, user: null }, true); }); test('increments count', () => { useStore.getState().increment(); expect(useStore.getState().count).toBe(1); }); test('fetch user', async () => { vi.spyOn(global, 'fetch').mockResolvedValue({ json: async () => ({ id: 1 }) }); await useStore.getState().fetchUser(1); expect(useStore.getState().user).toEqual({ id: 1 }); });