如何在 javascript 中模拟构造函数调用

How to mock constructor call in javascript

如何在派生 class 中模拟创建父 class 的构造函数。

这是我正在测试的例子。

myclass.js

class a {

  constructor() {
     console.log('i am from class a constructor');
   }
  foo() {
    console.log('i am from class a foo method');
  }
}


class b {

  constructor() {
     console.log('i am from class b constructor');
   }
  baz() {
    let obj = new a();
    a.foo();
    console.log('i am from class b baz method');
  }
}

这是我的单元测试,使用 Sinon.js 我在嘲笑。 我正在为 class b -> baz() 方法创建单元测试。我的期望是调用 baz() 方法不应该调用实际的 class a 并且它不应该打印 class a constructor.how 中的控制台我能实现这个吗? sinon.createStubInstance() 我曾经创建对象但是如何模拟构造函数?

myclass.test.js

describe('myclass' ()=> {
   it('should not call class a constructor', (done) => {
    let b_obj = new b()
    b_obj.baz();
    done()
   });
})

以上代码的输出打印

i am from class a constructor
i am from class a foo method
i am from class b baz method

上述代码的预期输出

// should be mocked .. i am from class a constructor
//should be mocked .. i am from class a foo method
i am from class b baz method

我做了一些重构并使用 proxyquire 模拟 class a

例如

a.js:

class a {
  constructor() {
    console.log('i am from class a constructor');
  }
  foo() {
    console.log('i am from class a foo method');
  }
}

module.exports = a;

b.js:

const a = require('./a');

class b {
  constructor() {
    console.log('i am from class b constructor');
  }
  baz() {
    let obj = new a();
    obj.foo();
    console.log('i am from class b baz method');
  }
}

module.exports = b;

b.test.js:

const b = require('./b');
const sinon = require('sinon');
const proxyquire = require('proxyquire');

describe('61108610', () => {
  it('should pass', () => {
    const aInstanceStub = { foo: sinon.stub() };
    const aStub = sinon.stub().returns(aInstanceStub);
    const b = proxyquire('./b', {
      './a': aStub,
    });
    const logSpy = sinon.spy(console, 'log');
    const b_obj = new b();
    b_obj.baz();
    sinon.assert.calledOnce(aStub);
    sinon.assert.calledOnce(aInstanceStub.foo);
    sinon.assert.calledWithExactly(logSpy, 'i am from class b baz method');
  });
});

带有覆盖率报告的单元测试结果:

  61108610
i am from class b constructor
i am from class b baz method
    ✓ should pass


  1 passing (30ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |   77.78 |      100 |      50 |   77.78 |                   
 a.js     |   33.33 |      100 |       0 |   33.33 | 3,6               
 b.js     |     100 |      100 |     100 |     100 |                   
----------|---------|----------|---------|---------|-------------------

源代码:https://github.com/mrdulin/expressjs-research/tree/master/src/Whosebug/61108610