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

Jest中如何为浏览器函数正确传入Mock DOM?

解决Jest中Mock DOM无效导致getElementById返回null的问题

问题根源

你的测试代码存在两个核心问题:

  • 模块加载时机错误:先引入了tested_file.js,之后才挂载自定义的document到global。此时被测函数里的document已经绑定了Jest初始的空DOM环境,后续替换global.document不会影响已加载模块里的引用。
  • 重复创建DOM环境:你已经在package.json中配置了testEnvironment: "jsdom",Jest会自动提供完整的浏览器DOM环境,手动引入jsdom包并创建实例会和内置环境冲突。

修复方案

1. 精简依赖配置

修改package.json,移除手动安装的jsdom包(jest-environment-jsdom已包含所需的jsdom功能),清理冗余配置:

{
  "scripts": {
    "js_test": "jest"
  },
  "jest": {
    "testEnvironment": "jsdom"
  },
  "devDependencies": {
    "jest": "^29.5.0",
    "jest-environment-jsdom": "^29.5.0",
    "text-encoding": "^0.7.0"
  }
}

执行命令移除多余依赖:

npm uninstall jsdom

2. 调整测试代码逻辑

把DOM初始化逻辑放到被测模块引入之前,或者在测试用例/前置钩子中动态设置DOM结构,确保被测函数执行时能获取到正确的DOM:

const { TextEncoder, TextDecoder } = require('text-encoding');
global.TextEncoder = TextEncoder;
global.TextDecoder = TextDecoder;

// 先初始化DOM结构
document.body.innerHTML = `
  <img id="id1" src="foo.jpg" />
`;

// 再引入被测函数
const { hello_world } = require("<path>/tested_file.js");

describe('hello_world', () => {
  test('returns correct id', () => {
    const x = hello_world();
    expect(x).toBe("id1");
  });
});

如果是多测试用例场景,推荐用beforeEach钩子在每个测试前重置DOM:

const { TextEncoder, TextDecoder } = require('text-encoding');
global.TextEncoder = TextEncoder;
global.TextDecoder = TextDecoder;

const { hello_world } = require("<path>/tested_file.js");

describe('hello_world', () => {
  beforeEach(() => {
    // 每次测试前重置DOM结构
    document.body.innerHTML = `
      <img id="id1" src="foo.jpg" />
    `;
  });

  test('returns correct id', () => {
    const x = hello_world();
    expect(x).toBe("id1");
  });
});

原理说明

当Jest使用jsdom环境时,会自动在global上挂载window、document等浏览器全局对象。只要在调用被测函数前设置好DOM结构,函数就能正确访问到对应的DOM元素。模块加载时会静态绑定当前的document引用,因此必须确保DOM初始化完成后再引入被测模块,或者在每次测试前重置DOM状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 01:37:09