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

如何Mock网站行为实现JavaScript函数单元测试(窗口场景)

模拟窗口尺寸测试JS函数的最佳实践

刚接触JS单元测试时,碰到这种依赖浏览器环境的场景确实头疼——想测试不同窗口尺寸下的函数行为,却被真实浏览器的限制卡得死死的。我来分享几个亲测有效的方案,帮你搞定这个问题,顺便聊聊工具组合的最佳实践。

一、用Sinon正确拦截窗口尺寸的读取

你之前尝试stub $.prototype.width没效果,是因为找错了拦截的对象。如果你的函数是通过$(window).width()获取尺寸,应该直接mock $(window)这个实例的方法;如果是用原生的window.innerWidth,那就直接stub全局属性。

场景1:函数用jQuery获取窗口尺寸

假设你的函数是这样的:

function adjustBackground() {
  const winWidth = $(window).width();
  const winHeight = $(window).height();
  $('#bg').css({ width: winWidth, height: winHeight });
}

正确的测试方式是用Sinon替换$(window)的返回值,模拟width/height方法:

// 测试前准备
beforeEach(() => {
  // 创建一个带stub方法的模拟window对象
  const mockWindow = sinon.stub({ width: () => {}, height: () => {} });
  // 让$调用window时返回这个模拟对象
  sinon.stub($, 'call').withArgs(window).returns(mockWindow);
});

// 测试后恢复原始状态
afterEach(() => {
  sinon.restore();
});

it('应该将背景调整为600x1600', () => {
  // 设置模拟的尺寸返回值
  $(window).width.returns(600);
  $(window).height.returns(1600);
  
  // 执行目标函数
  adjustBackground();
  
  // 断言背景尺寸正确
  expect($('#bg').css('width')).to.equal('600px');
  expect($('#bg').css('height')).to.equal('1600px');
});

场景2:函数用原生属性获取尺寸

如果函数直接用window.innerWidth/innerHeight,可以直接用Sinon stub全局属性:

beforeEach(() => {
  // 直接替换window的innerWidth和innerHeight值
  sinon.stub(window, 'innerWidth').value(600);
  sinon.stub(window, 'innerHeight').value(1600);
});

afterEach(() => {
  sinon.restore();
});

it('正确使用window原生尺寸', () => {
  adjustBackground();
  // 这里写你的断言逻辑,比如检查背景元素的尺寸
});

二、触发resize事件的正确姿势

你之前触发resize没效果,是因为先触发了事件再模拟尺寸——正确顺序应该是先模拟尺寸,再触发事件:

it('窗口resize时应该更新背景尺寸', () => {
  // 初始尺寸
  sinon.stub(window, 'innerWidth').value(800);
  sinon.stub(window, 'innerHeight').value(600);
  adjustBackground();
  expect($('#bg').css('width')).to.equal('800px');

  // 修改模拟的尺寸
  window.innerWidth.value = 1000;
  window.innerHeight.value = 800;
  
  // 触发resize事件
  window.dispatchEvent(new Event('resize'));
  
  // 断言尺寸已更新
  expect($('#bg').css('width')).to.equal('1000px');
});

三、工具组合的最佳实践

对于原生JS项目,我最推荐的组合是:

  • Mocha:测试运行器,灵活且社区生态成熟
  • Chai:断言库,支持BDD/TDD风格,语法友好
  • Sinon:专门处理spy/stub/mock,模拟依赖项的能力极强

如果是React、Vue这类框架项目,Jest会更省心——它内置了类似Sinon的mock功能,还集成了jsdom,不用额外配置就能模拟浏览器环境。

核心原则是:永远不要修改真实浏览器窗口,所有依赖环境的部分都用mock/stub替代,这样测试不仅更快,结果也更稳定,不会受浏览器差异影响。

四、Node环境测试:用jsdom模拟完整浏览器

如果你不想在真实浏览器里跑测试,完全可以用jsdom在Node环境模拟浏览器,直接设置窗口尺寸:

const { JSDOM } = require('jsdom');
const dom = new JSDOM('<html><body><div id="bg"></div></body></html>', {
  windowOptions: {
    innerWidth: 600,
    innerHeight: 1600
  }
});

// 把模拟的window和document挂到全局
global.window = dom.window;
global.document = dom.window.document;

// 之后引入jQuery和你的函数,就可以正常测试了
const $ = require('jquery')(window);
const { adjustBackground } = require('./your-module');

it('在jsdom中测试背景调整', () => {
  adjustBackground();
  expect($('#bg').css('width')).to.equal('600px');
});

这种方式完全脱离真实浏览器,适合CI/CD环境自动跑测试,也不会有iframe的CSS冲突问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:40:59