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

qvsjd97n  于 6个月前  发布在  Node.js
关注(0)|答案(3)|浏览(50)

因此,我有一些问题与构造函数,以及更多的继承类构造函数.我将从一些示例代码片段开始:
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
}


Mocha测试

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();
});

...


我已经尝试了一些事情,但总是发现父构造函数中的代码无论我做什么都能运行.我有一种感觉,这可能与MyClass在有机会存根之前需要Parent有关。
我也试过使用rewire来替换MyClass中的变量,但也没有joy;例如。

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


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

kqlmhetl

kqlmhetl1#

我还没有使用rewire,所以我不知道为什么它不工作,但使用proxyquire复制父构造函数会很好:

const MockParent = sinon.stub()
const MyClass = proxyquire('../../some/path', {
  './Parent': MockParent
})

字符串

w80xi6nr

w80xi6nr2#

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()

pkln4tw6

pkln4tw63#

我不确定这是否是最现代的方法,但我从一个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();
  });
});

字符串

相关问题