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

升级jest至29.x.x及安装jest-environment-jsdom后window.history.pushState失效

Jest 29.x.x + jsdom环境下history.pushState测试失效的解决办法

升级Jest到29.x.x版本并配套安装jest-environment-jsdom:29.x.x后,原本在Jest 27.5.0中正常运行的history.pushState测试代码会失效,示例代码如下:

window.history.pushState({}, 'Test page', '/123')
expect(window.location.href).toEqual('http://localhost/123')

问题原因

Jest 29所依赖的jsdom版本调整了history.pushState的模拟逻辑,不再自动同步更新window.location的属性值。这一改动更贴近真实浏览器的行为:真实浏览器中pushState仅修改历史记录栈和地址栏显示,不会触发页面导航,但jsdom在旧版本中存在非标准的同步更新location的行为,Jest 27依赖的jsdom版本保留了这个行为。

解决方案

方案1:手动Mock pushState并同步更新location

在测试中手动模拟pushState方法,让它在调用时同步修改window.location.href:

// 在测试文件的 beforeEach 中添加mock
beforeEach(() => {
  jest.spyOn(window.history, 'pushState').mockImplementation((_state, _title, url) => {
    if (url) {
      // 基于当前location构造新的href
      window.location.href = new URL(url, window.location.href).href;
    }
  });
});

// 测试后恢复原方法
afterEach(() => {
  jest.restoreAllMocks();
});

test('验证pushState修改地址', () => {
  window.history.pushState({}, 'Test page', '/123');
  expect(window.location.href).toEqual('http://localhost/123');
});

方案2:调整测试逻辑,验证pushState的调用参数

如果你的测试核心是验证pushState是否被正确调用(而非location.href的变化),可以直接断言pushState的调用情况:

test('验证pushState被正确调用', () => {
  const pushStateSpy = jest.spyOn(window.history, 'pushState');
  
  window.history.pushState({}, 'Test page', '/123');
  
  expect(pushStateSpy).toHaveBeenCalledWith({}, 'Test page', '/123');
});

方案3:确保Jest配置正确指定jsdom环境

检查你的jest.config.js(或package.json中的jest配置),确认已明确设置测试环境为jsdom:

// jest.config.js
module.exports = {
  testEnvironment: 'jsdom',
  // 其他配置...
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 02:26:19