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

如何用Jest和React Testing Library在TS中模拟含useRef的自定义异步Hook

在TypeScript环境下用Jest+React Testing Library测试带Ref的自定义Hook

针对你提供的useCustomHook,以下是具体的测试方案和代码示例:

先明确前提

你的Hook接收一个返回React.RefObject的函数作为参数,在useEffect中调用该函数获取ref的current值。测试核心是模拟这个ref getter函数,验证Hook的逻辑分支和返回结果。

步骤1:补充类型定义

首先确保测试文件中定义了Hook依赖的Iref类型,和业务代码保持一致:

interface Iref {
  // 根据实际业务补充属性,比如假设是DOM元素或自定义对象
  someProperty?: string;
}

步骤2:编写测试用例

使用@testing-library/react的renderHook(专门用于测试自定义Hook的工具),结合Jest的模拟函数来覆盖不同场景:

import { renderHook } from '@testing-library/react';
import { useCustomHook } from './useCustomHook';

interface Iref {
  testProp: string;
}

describe('useCustomHook', () => {
  // 测试正常ref场景
  it('初始化后设置initializedRef为true,并正确访问ref.current', () => {
    // 模拟ref的current值
    const mockRefCurrent: Iref = { testProp: 'test-content' };
    // 创建模拟的ref getter函数,追踪调用并返回预设的ref对象
    const mockRef = jest.fn(() => ({ current: mockRefCurrent }));

    // 渲染Hook并传入模拟的ref函数
    const { result } = renderHook(() => useCustomHook(mockRef));

    // 验证返回的状态是否正确
    expect(result.current.initializedRef).toBe(true);
    // 验证ref函数被调用过一次
    expect(mockRef).toHaveBeenCalledTimes(1);
    // 如果Hook中有对current的业务逻辑,这里可以添加对应断言(比如是否读取了current的属性)
  });

  // 测试ref.current为null的场景
  it('当ref.current为null时,仍能正常初始化', () => {
    const mockRef = jest.fn(() => ({ current: null }));

    const { result } = renderHook(() => useCustomHook(mockRef));

    expect(result.current.initializedRef).toBe(true);
    expect(mockRef).toHaveBeenCalledTimes(1);
    // 可添加针对null场景的业务逻辑断言
  });

  // 测试传入undefined ref的场景
  it('当传入undefined的ref时,仍能完成初始化', () => {
    // 类型断言适配Hook的参数类型要求
    const { result } = renderHook(() => 
      useCustomHook(undefined as unknown as () => React.RefObject<Iref>)
    );

    expect(result.current.initializedRef).toBe(true);
    // 若要验证ref未被调用,可传入jest.fn()的空模拟,再断言toHaveBeenCalledTimes(0)
  });
});

关键说明

  1. 无需模拟useRef:你的Hook中并没有内部调用useRef,而是接收外部传入的ref getter函数,所以直接模拟这个函数即可,不需要额外mock React的useRef。
  2. renderHook的作用:自动处理Hook的生命周期(比如触发useEffect执行),让你能直接获取Hook的返回结果。
  3. 类型适配:TypeScript环境下要确保模拟的ref函数类型和Hook参数一致,必要时用类型断言处理边界情况(比如undefined)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 00:31:08