如何使用Sinon来存根扩展的ES6类的构造函数

问题描述 投票:0回答:3

所以我在存根构造函数方面遇到了一些问题,更重要的是继承类构造函数...... 我将从一些示例代码片段开始:

Parent.js

module.exports = class Parent {
  constructor (){
    // code I don't want to run during tests
  }
}

MyClass.js

let Parent = require('path/to/Parent');

module.exports = class MyClass extends Parent {
  // no overridden constructor
}

摩卡测试

let MyClass = require('path/to/MyClass')

...

test('test1', (done) => {
  // I want to stub the MyClass/Parent constructor before creating a new instance
  // of MyClass so that the constructor code in Parent doesn't run

  let myClass = new MyClass();
  // assertions 'n' stuff
  return done();
});

...

我已经尝试了一些事情,但总是发现无论我做什么,Parent 构造函数中的代码都会运行...我有一种感觉,它可能与 MyClass 在有机会存根之前需要 Parent 有关.

我也尝试过使用 rewire 来替换 MyClass 中的变量,但也不高兴;例如

let MyClass = rewire('path/to/MyClass');
MyClass.__set__('Parent', sinon.stub());

关于如何实现我在这里想做的事情有什么建议/帮助吗?

javascript node.js ecmascript-6 mocha.js sinon
3个回答
1
投票

我没有使用过重新连线,所以我不确定为什么它不起作用,但使用 proxyquire

存根父构造函数可以正常工作
const MockParent = sinon.stub()
const MyClass = proxyquire('../../some/path', {
  './Parent': MockParent
})

0
投票
module.exports = class MyClass extends Parent {
  // no overridden constructor
}

等于:

module.exports = class MyClass extends Parent {
  constructor (...args) {
     super(...args) // be equal to Parent.call(this, ...args)
  }
}

所以,流程是 new MyClass() -> MyClass constructor() -> Parent.call() -> Parent constructor()


0
投票

我不确定这是否是最现代的方法,但是我从Sinon贡献者那里找到了这个解决方案

我已将他们的代码转换为通过测试:

import sinon from "sinon";

describe("Stubbing parent constructor but not child constructor", () => {
  afterEach(() => {
    sinon.restore();
  });

  it(`can intercept parent calls`, () => {
    let classAConstructorCalled = false;
    let classBConstructorCalled = false;
    let stubCalledFake = false;

    class A {
      constructor() {
        classAConstructorCalled = true;
      }
    }

    class B extends A {
      constructor() {
        super();
        classBConstructorCalled = true;
      }
    }

    Object.setPrototypeOf(
      B,
      sinon.stub().callsFake(function () {
        stubCalledFake = true;
      })
    );

    new B();

    expect(classAConstructorCalled).toBeFalse();
    expect(classBConstructorCalled).toBeTrue();
    expect(stubCalledFake).toBeTrue();
  });
});

© www.soinside.com 2019 - 2024. All rights reserved.