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

如何用Vitest测试自定义Hook内部的saveNewCustomSize函数?

解决Vitest测试自定义Hook时断言updateStaticCustom调用失败的问题

以下是针对你遇到的问题的排查方向和解决方案:

1. 确认触发路径的有效性

首先要排查rerunCustomQuery是否真的能触发saveNewCustomSize:

  • 检查Hook内部逻辑:rerunCustomQuery执行时是否存在条件分支(比如状态判断、参数校验),导致saveNewCustomSize未被调用。比如有没有传入的参数不满足触发条件?
  • 如果saveNewCustomSize依赖Hook内部的某些状态,要确保测试时这些状态处于正确的初始值(可以通过renderHook的initialProps预设状态,或者调用Hook返回的状态修改方法设置)。

2. 修正mock函数的设置与重置

确保updateStaticCustom的mock是正确的:

  • 用vi.fn()创建mock函数后,要保证Hook实际引用的是这个mock实例(比如Hook通过props或context接收该函数时,测试中必须注入这个mock)。
  • 每次测试前调用mockFn.mockClear()或vi.clearAllMocks(),清除之前测试的调用记录,避免干扰当前断言。

3. 调整断言的匹配方式

直接断言对象相等时,容易因为引用不一致导致失败,建议改用以下方式:

  • 用expect.deepEqual()做深度值匹配:
    expect(mockUpdateStaticCustom).toHaveBeenCalledWith(expect.deepEqual(expectedPayload))
    
  • 用expect.objectContaining()断言关键属性匹配(适合只关心部分字段的场景):
    expect(mockUpdateStaticCustom).toHaveBeenCalledWith(expect.objectContaining({
      size: 'custom',
      value: 100
    }))
    

4. 处理异步操作

如果saveNewCustomSize或updateStaticCustom是异步函数,必须等待异步操作完成后再断言:

  • 调用rerunCustomQuery后,使用waitFor包裹断言:
    await waitFor(() => {
      expect(mockUpdateStaticCustom).toHaveBeenCalledWith(expect.deepEqual(expectedPayload))
    })
    
  • 如果rerunCustomQuery本身是异步函数,要记得用await调用。

测试代码示例

import { vi, expect, waitFor } from 'vitest';
import { renderHook } from '@testing-library/react';
import useRerunCustomQuery from './useRerunCustomQuery';

describe('useRerunCustomQuery', () => {
  it('triggers updateStaticCustom with correct payload', async () => {
    // 创建mock函数
    const mockUpdateStaticCustom = vi.fn();
    // 渲染Hook并注入mock
    const { result } = renderHook(() => useRerunCustomQuery({
      updateStaticCustom: mockUpdateStaticCustom,
      // 传入Hook所需的其他初始参数
      initialSize: 'default'
    }));

    // 调用rerunCustomQuery,传入触发saveNewCustomSize的必要参数
    await result.current.rerunCustomQuery({ targetSize: 'custom' });

    // 等待异步操作完成并断言
    const expectedPayload = { size: 'custom', value: 200 };
    await waitFor(() => {
      expect(mockUpdateStaticCustom).toHaveBeenCalledWith(expect.deepEqual(expectedPayload));
    });
  });
});

额外提醒:可以在Hook内部saveNewCustomSize执行时临时添加日志,确认它是否被调用以及构造的payload是否符合预期,帮助快速定位问题。

内容的提问来源于stack exchange,提问作者Muhammad Umer Nisar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 21:22:22