簡體   English   中英

ES2016 類,Sinon Stub 構造函數

[英]ES2016 Class, Sinon Stub Constructor

我正在嘗試與 sinon 和 es2016 進行超級調用,但我運氣不佳。 任何想法為什么這不起作用?

運行 Node 6.2.2,這可能是它的類/構造函數實現的問題。

.babelrc 文件:

{
  "presets": [
    "es2016"
  ],
  "plugins": [
    "transform-es2015-modules-commonjs",
    "transform-async-to-generator"
  ]
}

測試:

import sinon from 'sinon';

class Foo {
  constructor(message) {
    console.log(message)
  }
}

class Bar extends Foo {
  constructor() {
    super('test');
  }
}

describe('Example', () => {
  it('should stub super.constructor call', () => {
    sinon.stub(Foo.prototype, 'constructor');

    new Bar();

    sinon.assert.calledOnce(Foo.prototype.constructor);
  });
});

結果:

test
AssertError: expected constructor to be called once but was called 0 times
    at Object.fail (node_modules\sinon\lib\sinon\assert.js:110:29)
    at failAssertion (node_modules\sinon\lib\sinon\assert.js:69:24)
    at Object.assert.(anonymous function) [as calledOnce] (node_modules\sinon\lib\sinon\assert.js:94:21)
    at Context.it (/test/classtest.spec.js:21:18)

注意:這個問題似乎只發生在構造函數上。 我可以毫無問題地監視從父類繼承的方法。

由於 JavaScript 實現繼承的方式,您需要 setPrototypeOf 子類。

const sinon = require("sinon");

class Foo {
  constructor(message) {
    console.log(message);
  }
}

class Bar extends Foo {
  constructor() {
    super('test');
  }
}

describe('Example', () => {
  it('should stub super.constructor call', () => {
    const stub = sinon.stub().callsFake();
    Object.setPrototypeOf(Bar, stub);

    new Bar();

    sinon.assert.calledOnce(stub);
  });
});

你需要spy而不是stub

sinon.spy(Foo.prototype, 'constructor');

describe('Example', () => {
  it('should stub super.constructor call', () => {
    const costructorSpy = sinon.spy(Foo.prototype, 'constructor');
    new Bar();
    expect(costructorSpy.callCount).to.equal(1);
  });
});

*****更新****** 以上未按預期工作,我以這種方式添加並且現在正在工作。

 describe('Example', () => {
    it('should stub super.constructor call', () => {
      const FooStub = spy(() => sinon.createStubInstance(Foo));
      expect(FooStub).to.have.been.calledWithNew;
    });
 });

它對我也不起作用。 我管理了一個對我有用的解決方法,我也使用間諜:

class FakeSchema {
  constructor(newCar) {
    this.constructorCallTest();
    this.name = newCar.name;
  }

  constructorCallTest() {
    mochaloggger.log('constructor was called');
  }

}

// spy that tracks the contsructor call
var fakeSchemaConstrSpy = sinon.spy(FakeCarSchema.prototype,'constructorCallTest');

希望有幫助

如果您在瀏覽器環境中,以下也適用:

let constructorSpy = sinon.spy(window, 'ClassName');

例如,這將適用於 Jasmine。

Mocha 而是在 Node 環境中運行,沒有window 您要查找的變量是global變量

添加到setPrototypeOf公認答案中,在存根父類並將原始父類替換為setPrototypeOf時,可能會忽略一個步驟。

💡 此外,為了避免它破壞后續的測試,最好在最后回退原始父類,例如:

const sinon = require("sinon");
    
class Foo {
  constructor(message) {
    console.log(message);
   }
}
    
class Bar extends Foo {
  constructor() {
    super('test');
  }
}
    
describe('Bar constructor', () => {
  it('should call super', () => {
    const stub = sinon.stub().callsFake();
    const original = Object.getPrototypeOf(Bar);  // Bar.__proto__ === Foo
    

    Object.setPrototypeOf(Bar, stub);             // Bar.__proto__ === stub
    
    new Bar();
    
    sinon.assert.calledOnce(stub);
    Object.setPrototypeOf(Bar, original);         // Bar.__proto__ === Foo

  });
});

補充是

// saving the reference to the original parent class:
const original = Object.getPrototypeOf(Bar);
// setting back the original parent class after stubbing and the assertion:
Object.setPrototypeOf(Bar, original); 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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