簡體   English   中英

如何使用 Sinon 存根 ES6 類構造函數

[英]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 定義為存根)。

亮點:

  • 使用stub calledWithNew()檢查 Bar 是否使用 new 調用。
  • 不使用箭頭函數
  • 使用 chai 的expect instanceof ,因為 Foo 的構造函數會添加屬性bar ,然后可以添加額外的期望來檢查屬性 bar ,即檢查 Foo 的構造函數是否運行。
// @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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM