React无限滚动自定义hook单元测试失败,求修正方案
修正useInfiniteScroll的单元测试
你的测试失败主要有几个核心问题:
- 未给hook返回的ref绑定真实DOM元素,导致
ref.current为null,滚动触发条件不成立 - 没有模拟符合阈值的滚动位置,无法触发
setIsFetching(true)进而调用回调 - 断言对象错误,应该验证传入hook的回调函数,而非自定义的未关联的
handleScroll - 防抖函数的延迟未处理,导致逻辑未及时触发
以下是修正后的测试代码:
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
相关产品推荐
相关产品推荐

