我如何监视注入的构造函数?

时间:2016-12-29 17:41:09

标签: javascript node.js mocha sinon chai

我有Manager大量使用serialport模块,并希望使用模拟版本的serialport运行单元测试。我重写了我的经理模块以利用依赖注入:

// file: manager.js

function Manager(SerialPort, device, baudRate) {
  this._device = device;
  this._serialPort = new SerialPort(device, {autoOpen: false, baudRate: baudRate })
};
Manager.prototype.constructor = Manager;

现在我想测试一下,看到正确的参数传递给new SerialPort()调用。我坚持如何正确地存根/模拟构造函数。这就是我到目前为止所拥有的:

// file: manager-test.js

function MockSerialPort(device, options) {}

describe('Manager', function() {
  describe('constructor', function() {
    it('instantiates a serial port with correct baud rate', function() {
      const manager = new Manager(MockSerialPort, '/dev/tty', 9600);
      expect(<something>).to.be.calledWith('/dev/tty', {autoOpen: false, baudRate: 9600});
    });
  });
});

显然我有几个漏洞

  在我的脑海里,哎呀,不,我的意思是

在我的代码中。我需要什么来填写这个测试?

更新

正如@cdhowie指出的那样,如果我可以将实例化的SerialPort对象传递给Manager,那么生活会更容易。由于一些误导性的文档,我并不认为使用SerialPort API是可行的,但是由于他的帮助,现在的实现看起来像:

function Manager(serialPort) {
  this._serialPort = serialPort;
}
Manager.prototype.constructor = Manager;

这意味着在我的测试中,我只是创建像SerialPort对象一样的外观,游泳和嘎嘎声。然后,殴打和间谍变得微不足道。

1 个答案:

答案 0 :(得分:1)

只需使用匿名函数将其参数存储在测试范围内:

let ctorArgs;
const manager = new Manager(function () {
    ctorArgs = Array.prototype.slice.call(arguments);
}, '/dev/tty', 9600);

// Assert against the contents of ctorArgs

旁注:为什么要将构造函数和参数传递给Manager而不是仅传递构造的SerialPort对象?除非Manager需要使用相同的参数创建多个对象,否则给它创建对象的负担似乎有点傻。