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

如何在Jest中获取document.body样式?如何测试useEffect中的代码?

在Jest中测试document.body样式与useEffect逻辑

一、在Jest中获取document.body的样式

Jest基于jsdom模拟浏览器环境,你可以通过两种方式获取document.body的样式:

  • 获取内联样式:直接访问document.body.style.xxx,比如document.body.style.overflow就能拿到代码里设置的内联overflow值。
  • 获取计算后样式:如果要获取最终生效的样式(比如继承或CSS类设置的),用window.getComputedStyle(document.body).xxx,比如window.getComputedStyle(document.body).overflow。

二、测试目标useEffect的逻辑

先把要测试的代码整理出来:

useEffect(() => {
  let top = 10;
  if (window.innerWidth > frame.current.clientHeight) {
    top = Math.max(top, (window.innerHeight - frame.current.clientHeight) / 2 - top);
  }
  frame.current.style.marginTop = `${top}px`;
  document.body.style.overflow = 'hidden';
  return () => {
    document.body.style.overflow = 'auto';
  }
}, []); // 假设依赖为空,实际根据组件依赖调整

测试步骤与用例

1. 基础准备

Jest自带jsdom环境,不用额外配置。核心是模拟frame这个ref、窗口的innerWidth和innerHeight属性,以及组件的挂载/卸载流程。

2. 测试窗口宽度≤frame高度的场景

import { render, cleanup } from '@testing-library/react';
import YourComponent from './YourComponent';

// 每次测试后清理DOM,避免污染
afterEach(cleanup);

test('窗口宽度小于等于frame高度时,设置正确marginTop并隐藏body滚动', () => {
  // 模拟frame ref
  const mockFrameRef = {
    current: {
      clientHeight: 500,
      style: {}
    }
  };
  // 模拟窗口尺寸
  Object.defineProperty(window, 'innerWidth', { value: 400 });
  Object.defineProperty(window, 'innerHeight', { value: 800 });

  // 渲染组件,这里假设组件通过props接收ref,实际根据组件结构调整
  render(<YourComponent frameRef={mockFrameRef} />);

  // 验证marginTop为初始值10px
  expect(mockFrameRef.current.style.marginTop).toBe('10px');
  // 验证body的overflow被设为hidden
  expect(document.body.style.overflow).toBe('hidden');
});

3. 测试窗口宽度>frame高度的场景

test('窗口宽度大于frame高度时,计算正确的marginTop并隐藏body滚动', () => {
  const mockFrameRef = {
    current: {
      clientHeight: 500,
      style: {}
    }
  };
  Object.defineProperty(window, 'innerWidth', { value: 600 });
  Object.defineProperty(window, 'innerHeight', { value: 800 });

  render(<YourComponent frameRef={mockFrameRef} />);

  // 计算预期top值:(800-500)/2 -10 = 140,Math.max(10,140)=140
  expect(mockFrameRef.current.style.marginTop).toBe('140px');
  expect(document.body.style.overflow).toBe('hidden');
});

4. 测试组件卸载时恢复body滚动

test('组件卸载时,恢复body的overflow为auto', () => {
  const mockFrameRef = {
    current: {
      clientHeight: 500,
      style: {}
    }
  };
  Object.defineProperty(window, 'innerWidth', { value: 400 });

  // 拿到unmount方法,用于主动卸载组件
  const { unmount } = render(<YourComponent frameRef={mockFrameRef} />);
  
  // 执行卸载
  unmount();
  
  // 验证overflow恢复为auto
  expect(document.body.style.overflow).toBe('auto');
});

注意事项

  • 如果frame是组件内部用useRef创建的,给frame元素加data-testid="frame",然后通过screen.getByTestId('frame')获取元素,再用Object.defineProperty模拟它的clientHeight。
  • 窗口属性必须用Object.defineProperty模拟,直接赋值window.innerWidth不会生效,因为这些是只读属性。
  • 确保测试用例之间相互独立,避免残留状态影响结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 20:55:30