我有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对象一样的外观,游泳和嘎嘎声。然后,殴打和间谍变得微不足道。
答案 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
需要使用相同的参数创建多个对象,否则给它创建对象的负担似乎有点傻。