所以我在存根构造函数方面遇到了一些问题,更重要的是继承类构造函数...... 我将从一些示例代码片段开始:
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());
关于如何实现我在这里想做的事情有什么建议/帮助吗?
我没有使用过重新连线,所以我不确定为什么它不起作用,但使用 proxyquire:
存根父构造函数可以正常工作const MockParent = sinon.stub()
const MyClass = proxyquire('../../some/path', {
'./Parent': MockParent
})
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()
我不确定这是否是最现代的方法,但是我从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();
});
});