我正在尝试使用Sinon的存根类构造函数。
常规方法的存根' omg'工作正常,但构造函数的存根未通过测试,并且真正的'调用构造函数而不是存根。
关于我需要什么语法才能正确存根的想法?
class Foo {
constructor() {
this.bar = new Bar();
}
omg() {
this.bar.omg();
}
}
class Bar {
constructor() {
console.log('In bar constructor');
}
omg() {
console.log('In bar omg');
}
}
const sandbox = sinon.createSandbox();
sandbox.stub(Bar.prototype, 'constructor');
sandbox.stub(Bar.prototype, 'omg');
describe('Foo', () => {
describe('Constructor', () => {
it('Should instantiate bar', () => {
const foo = new Foo();
expect(Bar.prototype.constructor.called).to.be.true;
});
});
describe('Omg', () => {
it("Should call Bar's omg method', () => {
const foo = new Foo();
foo.omg();
expect(Bar.prototype.omg.called).to.be.true;
});
});
});

答案 0 :(得分:0)
已经2年多了,这意味着很难。 :)
当很难做到时,则需要重构代码。
下面的示例可行,但可能无法在现实世界中使用(需要在定义Foo之前将Bar定义为存根)。
要点:
// @file stackoverflow.js
const sinon = require('sinon');
const { expect } = require('chai');
const sandbox = sinon.createSandbox();
// Define Bar as a stub.
const Bar = sandbox.stub();
const BarOmgFn = sinon.fake();
Bar.prototype.omg = BarOmgFn;
// class Bar {
// constructor() {
// console.log('In bar constructor');
// }
// omg() {
// console.log('In bar omg');
// }
// }
class Foo {
constructor() {
this.bar = new Bar();
}
omg() {
this.bar.omg();
}
}
describe('Foo', function () {
after(function () {
sandbox.restore();
});
describe('Constructor', function () {
it('Should instantiate bar', function () {
const foo = new Foo();
// Check whether Bar called with new.
expect(Bar.calledWithNew()).to.equal(true);
// Check bar property.
expect(foo.bar).to.be.instanceOf(Bar);
});
});
describe('Omg', () => {
it("Should call Bar's omg method", function () {
const foo = new Foo();
foo.omg();
expect(BarOmgFn.calledOnce).to.equal(true);
});
});
});
使用mocha运行示例:
$ npx mocha stackoverflow.js
Foo
Constructor
✓ Should instantiate bar
Omg
✓ Should call Bar's omg method
2 passing (14ms)
$
从设计模式的角度来看,Foo类高度依赖于Bar类。重构可以使用dependency injection pattern。例如:对Foo类的简单更改,需要1个参数,它是Bar本身或Bar的实例。这项更改使代码更易于测试。
class Foo {
// Now constructor need 1 argument
constructor(Bar) {
this.bar = new Bar();
}
omg() {
this.bar.omg();
}
}
希望这会有所帮助。