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

如何使用Sinon Stub window.innerWidth与innerHeight属性?

解决Sinon无法Stub window.innerWidth/innerHeight的问题

我懂你遇到的困扰——浏览器原生的window.innerWidth和innerHeight是只读属性,它们的属性描述符默认是不可配置的,所以直接用Sinon的sandbox.stub().get()不会生效。下面给你几个可行的解决方案:

方法1:先修改属性描述符,再Stub

因为这类原生属性默认configurable: false,Sinon没法直接覆盖它的getter。我们需要先把它改成可配置的,再进行Stub:

describe('test', () => {
  let sandbox;

  beforeEach(() => {
    sandbox = sinon.sandbox.create();

    // 先修改window.innerWidth/innerHeight的属性描述符,开启可配置性
    Object.defineProperty(window, 'innerWidth', {
      configurable: true,
      writable: true,
    });
    Object.defineProperty(window, 'innerHeight', {
      configurable: true,
      writable: true,
    });

    // 现在可以正常Stub了,两种写法都支持:
    // 直接设值
    sandbox.stub(window, 'innerWidth').value(1000);
    sandbox.stub(window, 'innerHeight').value(1000);

    // 或者用getter函数
    // sandbox.stub(window, 'innerWidth').get(() => 1000);
    // sandbox.stub(window, 'innerHeight').get(() => 1000);
  });

  afterEach(() => {
    sandbox.restore();
    // 可选:恢复原属性的不可配置性,避免影响其他测试
    Object.defineProperty(window, 'innerWidth', {
      configurable: false,
      writable: false,
    });
    Object.defineProperty(window, 'innerHeight', {
      configurable: false,
      writable: false,
    });
  });

  it('should do a thing', () => {
    console.log(window.innerWidth); // 现在会输出1000了
  });
});

方法2:简化版(适合jsdom环境)

如果你是在jsdom(比如Jest默认环境)下测试,甚至可以不用Sinon,直接重写属性:

beforeEach(() => {
  Object.defineProperty(window, 'innerWidth', {
    value: 1000,
    configurable: true,
  });
});

afterEach(() => {
  delete window.innerWidth;
});

当然如果项目统一用Sinon做Stub,方法1会更符合你的测试习惯。

关键原理

浏览器原生的innerWidth/innerHeight这类属性,默认的属性描述符是:

Object.getOwnPropertyDescriptor(window, 'innerWidth');
// 返回:{ value: 1024, writable: false, enumerable: true, configurable: false }

因为configurable: false,所以任何试图修改属性定义的操作(包括Sinon的Stub)都会被忽略。必须先把configurable改成true,才能让Sinon成功覆盖它的取值逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:30:50