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

React无限滚动自定义hook单元测试失败,求修正方案

修正useInfiniteScroll的单元测试

你的测试失败主要有几个核心问题:

  1. 未给hook返回的ref绑定真实DOM元素,导致ref.current为null,滚动触发条件不成立
  2. 没有模拟符合阈值的滚动位置,无法触发setIsFetching(true)进而调用回调
  3. 断言对象错误,应该验证传入hook的回调函数,而非自定义的未关联的handleScroll
  4. 防抖函数的延迟未处理,导致逻辑未及时触发

以下是修正后的测试代码:

import { renderHook, act } from '@testing-library/react';
import useInfiniteScroll from './useInfiniteScroll';
import { fireEvent } from '@testing-library/react';

jest.useFakeTimers();

test('should trigger callback when scroll reaches threshold', () => {
  // 1. 创建模拟DOM元素并设置高度参数
  const mockElement = document.createElement('div');
  mockElement.offsetHeight = 1000; // 模拟容器总高度
  Object.defineProperty(window, 'innerHeight', { value: 500 }); // 模拟视口高度

  // 2. 定义要验证的回调函数
  const mockCallback = jest.fn();

  // 3. 渲染hook并绑定ref到模拟元素
  const { result } = renderHook(() => useInfiniteScroll(mockCallback));
  act(() => {
    result.current[0].current = mockElement;
  });

  // 4. 模拟滚动到触发阈值的位置并触发防抖
  act(() => {
    window.scrollY = 900; // 500+900=1400 >= 1000-10=990,满足触发条件
    fireEvent.scroll(window);
    jest.runAllTimers(); // 跳过防抖的100ms延迟,直接执行逻辑
  });

  // 5. 断言回调函数被调用
  expect(mockCallback).toHaveBeenCalled();
});

关键修正点说明:

  • 绑定模拟DOM:给ref.current赋值模拟div,确保hook内部的ref.current不为null
  • 模拟滚动条件:设置window.innerHeight和scrollY,让触发无限滚动的阈值条件成立
  • 处理防抖:用jest.useFakeTimers()和jest.runAllTimers()跳过防抖延迟,直接执行后续逻辑
  • 正确断言目标:验证传入hook的mockCallback是否被调用,这才是hook的核心行为输出

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 02:48:19