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

如何在Jest中模拟DOM方法?及指定useEffect代码的模拟方案

在Jest中模拟DOM方法及目标代码测试方案

一、核心模拟思路

Jest内置jsdom环境可模拟浏览器DOM,但针对链式调用的DOM方法,需分层mock每个调用步骤:

  • 先mock document.getElementById,让它返回带有querySelector方法的对象
  • 再mock querySelector,让它返回带有setAttribute方法的对象
  • 最后验证setAttribute是否按预期被调用

二、具体测试代码实现

假设目标逻辑在组件FormComponent.jsx中,对应的测试文件FormComponent.test.jsx代码如下:

import { render } from '@testing-library/react';
import FormComponent from './FormComponent';

describe('FormComponent', () => {
  it('sets input type to password on component mount', () => {
    // 1. 跟踪setAttribute的调用
    const mockSetAttribute = jest.fn();
    // 2. 模拟querySelector返回带setAttribute的元素
    const mockQuerySelector = jest.fn(() => ({ setAttribute: mockSetAttribute }));
    // 3. 模拟getElementById返回带querySelector的元素
    const mockGetElementById = jest.fn(() => ({ querySelector: mockQuerySelector }));
    
    // 替换原生document.getElementById为mock函数
    global.document.getElementById = mockGetElementById;

    // 渲染组件触发useEffect
    render(<FormComponent />);

    // 验证各方法的调用参数是否正确
    expect(mockGetElementById).toHaveBeenCalledWith('firstname');
    expect(mockQuerySelector).toHaveBeenCalledWith('input-field');
    expect(mockSetAttribute).toHaveBeenCalledWith('type', 'password');
  });
});

三、边界场景测试

如果DOM元素可能不存在,可调整mock来测试容错逻辑:

it('does nothing when target elements do not exist', () => {
  const mockSetAttribute = jest.fn();
  // 模拟querySelector返回null
  const mockQuerySelector = jest.fn(() => null);
  const mockGetElementById = jest.fn(() => ({ querySelector: mockQuerySelector }));
  
  global.document.getElementById = mockGetElementById;

  render(<FormComponent />);

  // 确认setAttribute未被调用
  expect(mockSetAttribute).not.toHaveBeenCalled();
});

四、测试后清理

为避免mock影响其他测试用例,可在每个测试结束后恢复原生方法:

afterEach(() => {
  jest.restoreAllMocks();
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 05:30:52