[英]How to stub ES6 class constructors with Sinon
我正在嘗試使用 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; }); }); });
它已經超過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 類。 重構可以使用依賴注入模式。 例如:通過需要 1 個參數,即 Bar 本身或 Bar 的實例,對類 Foo 進行簡單更改。 此更改使代碼更易於測試。
class Foo {
// Now constructor need 1 argument
constructor(Bar) {
this.bar = new Bar();
}
omg() {
this.bar.omg();
}
}
希望這會有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.