You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vitest+Vue Testing Library多测试用例Mock不同数据报错求解决方案

解决Vitest中为不同测试用例设置独立Mock数据的问题

问题根源分析

你遇到的问题核心有两个:

  • 笔误导致Mock未正确重置:beforeEach里调用的是useDivisionWidgetsQuery.mockReset(),但实际Mock的是useQuery1,这使得第一个测试的Mock数据残留到第二个测试中,引发数据混乱。
  • 未处理异步查询的渲染时机:组件中useQuery1是异步逻辑,直接用screen.getByText同步查询DOM时,可能还未完成数据渲染,从而触发错误。

修正后的测试代码

vi.mock('@/dashboard/queries/useQuery1')

describe('Widget1', () => {
  beforeEach(() => {
    // 正确重置目标Mock,确保每个测试的Mock状态独立
    useQuery1.mockReset()
  })

  test('test 1: 显示Future标题', async () => {
    // 使用mockResolvedValue而非once,确保组件内所有调用都返回该数据
    useQuery1.mockResolvedValue({
      data1: {
        amount: 0,
        date: '2021-01-01',
      },
      data2: { amount: 0 },
      data3: { amount: 0 },
      data4: { amount: 0 },
      data5: {
        total: 0,
        url: 'https://www.google.com',
      },
    })

    render(Widget1, {
      props: props,
    })

    // 使用findByText异步查询,等待异步渲染完成
    const futureTitle = await screen.findByText('Future')
    expect(futureTitle).toBeInTheDocument()
  })

  test('test 2: 不显示Future标题', async () => {
    useQuery1.mockResolvedValue({
      data1: null, // 自定义的Mock数据
      data2: { amount: 0 },
      data3: { amount: 0 },
      data4: { amount: 0 },
      data5: {
        total: 0,
        url: 'https://www.google.com',
      },
    })

    render(Widget1, {
      props: props,
    })

    // 用waitFor配合queryByText,确保组件渲染完成后元素确实不存在
    await waitFor(() => {
      expect(screen.queryByText('Future')).not.toBeInTheDocument()
    })
  })
})

关键修正点说明

  1. 修正Mock重置对象:将useDivisionWidgetsQuery.mockReset()改为useQuery1.mockReset(),确保每次测试前清空Mock的调用记录和返回值,避免跨测试污染。
  2. 替换mockResolvedValueOnce为mockResolvedValue:如果组件内多次调用useQuery1,mockResolvedValueOnce只会生效一次,后续调用会返回undefined导致组件报错。mockResolvedValue会让所有调用都返回指定数据,更适合单测试用例的独立Mock场景。
  3. 异步DOM查询处理:
    • await screen.findByText:这是Vue Testing Library推荐的异步查询方式,会自动等待元素出现(默认超时1000ms)。
    • waitFor + queryByText:getByText在元素不存在时会直接抛出错误,而queryByText会返回null,配合waitFor可以确保组件渲染完成后元素确实不存在。

额外注意事项

  • 如果useQuery1基于TanStack Query(原React Query),可以在测试中给每个用例创建独立的QueryClient实例并包裹QueryClientProvider,避免跨测试的缓存污染。
  • 若仍有问题,可在beforeEach中用useQuery1.mockImplementation(() => ({ isLoading: false, data: ... }))显式定义Mock的返回结构,确保组件能正确解构数据。

内容的提问来源于stack exchange,提问作者Yz_

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 11:43:22