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

如何在Jest中测试window.scrollY相关代码并满足测试覆盖率要求?

Jest测试controlNavbar函数方案

测试前准备

确保测试环境已安装jest和@testing-library/react(或其他React测试相关依赖),我们需要模拟window对象、setScrollUp和setLastScrollY状态更新函数,以及lastScrollY变量。

测试用例编写

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

// 封装待测试逻辑,便于传入依赖项
const setupControlNavbar = (lastScrollY, setScrollUp, setLastScrollY) => {
  const controlNavbar = () => {
    if (typeof window !== 'undefined') {
      if (window.scrollY > lastScrollY) {
        setScrollUp(false);
      }
      if (window.scrollY < lastScrollY) {
        setScrollUp(true);
      }
      setLastScrollY(window.scrollY);
    }
  };
  return controlNavbar;
};

describe('controlNavbar function', () => {
  let originalWindow;
  // 测试前保存原始window对象,测试后恢复
  beforeEach(() => {
    originalWindow = global.window;
    global.window = { scrollY: 0 };
  });

  afterEach(() => {
    global.window = originalWindow;
  });

  it('window未定义时不执行任何操作', () => {
    global.window = undefined;
    const mockSetScrollUp = jest.fn();
    const mockSetLastScrollY = jest.fn();
    const controlNavbar = setupControlNavbar(100, mockSetScrollUp, mockSetLastScrollY);

    controlNavbar();

    expect(mockSetScrollUp).not.toHaveBeenCalled();
    expect(mockSetLastScrollY).not.toHaveBeenCalled();
  });

  it('scrollY大于lastScrollY时,设置scrollUp为false并更新lastScrollY', () => {
    global.window.scrollY = 200;
    const mockSetScrollUp = jest.fn();
    const mockSetLastScrollY = jest.fn();
    const controlNavbar = setupControlNavbar(100, mockSetScrollUp, mockSetLastScrollY);

    act(() => {
      controlNavbar();
    });

    expect(mockSetScrollUp).toHaveBeenCalledWith(false);
    expect(mockSetLastScrollY).toHaveBeenCalledWith(200);
  });

  it('scrollY小于lastScrollY时,设置scrollUp为true并更新lastScrollY', () => {
    global.window.scrollY = 50;
    const mockSetScrollUp = jest.fn();
    const mockSetLastScrollY = jest.fn();
    const controlNavbar = setupControlNavbar(100, mockSetScrollUp, mockSetLastScrollY);

    act(() => {
      controlNavbar();
    });

    expect(mockSetScrollUp).toHaveBeenCalledWith(true);
    expect(mockSetLastScrollY).toHaveBeenCalledWith(50);
  });

  it('scrollY等于lastScrollY时,不修改scrollUp但更新lastScrollY', () => {
    global.window.scrollY = 100;
    const mockSetScrollUp = jest.fn();
    const mockSetLastScrollY = jest.fn();
    const controlNavbar = setupControlNavbar(100, mockSetScrollUp, mockSetLastScrollY);

    act(() => {
      controlNavbar();
    });

    expect(mockSetScrollUp).not.toHaveBeenCalled();
    expect(mockSetLastScrollY).toHaveBeenCalledWith(100);
  });
});

关键说明

  • 用beforeEach和afterEach维护window对象的纯净性,避免测试用例间互相干扰
  • 用jest.fn()模拟状态更新函数,方便断言调用情况和参数
  • 用act()包裹函数调用,确保React状态更新的副作用被正确捕获
  • 覆盖了所有分支场景:window不存在、scrollY大于/小于/等于lastScrollY

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 14:10:28