ES2016 Class,Sinon Stub构造函数

时间:2016-10-26 19:59:32

标签: javascript node.js mocha sinon babel

我正试图与sinon和es2016进行超级电话,但我没有太多运气。任何想法为什么这不起作用?

运行节点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)

注意:这个问题似乎只发生在构造函数中。我可以窥探从父类继承的方法而没有任何问题。

5 个答案:

答案 0 :(得分:6)

由于JavaScript实现继承的方式,您需要设置subClas的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);
  });
});

答案 1 :(得分:0)

您需要top_n.sort(key=lambda x: (-x[1], x[0])) 而不是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);
  });
});

答案 2 :(得分:0)

它对我也不起作用。我管理了一个适用于我的解决方法,我也使用间谍:

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');

希望这很有用

答案 3 :(得分:0)

如果您在浏览器环境中,以下内容也适用:

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

例如,这适用于Jasmine。

Mocha反而在Node环境中运行,没有window。您要查找的变量是global

答案 4 :(得分:0)

添加到文山的accepted answer中,在stub父类和用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);