我如何监视注入的构造函数?
How do I spy on an injected constructor?
我有一个 Manager
大量使用 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()
调用。我一直在研究如何正确 stub/mock 构造函数。这是我目前所拥有的:
// 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 对象传递给管理器,生活会更轻松。由于一些误导性文档,我认为使用 SerialPort API 是不可能的,但多亏了他的帮助,现在的实现看起来像:
function Manager(serialPort) {
this._serialPort = serialPort;
}
Manager.prototype.constructor = Manager;
这意味着在我的测试中,我只是创建了一些外观、游泳和嘎嘎声都像 SerialPort 对象的东西。存根和监视就变得微不足道了。
只需使用一个将其参数存储在测试范围内的匿名函数:
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
需要创建多个具有相同参数的对象,否则将创建对象的负担交给它似乎有点傻。
我有一个 Manager
大量使用 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()
调用。我一直在研究如何正确 stub/mock 构造函数。这是我目前所拥有的:
// 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 对象传递给管理器,生活会更轻松。由于一些误导性文档,我认为使用 SerialPort API 是不可能的,但多亏了他的帮助,现在的实现看起来像:
function Manager(serialPort) {
this._serialPort = serialPort;
}
Manager.prototype.constructor = Manager;
这意味着在我的测试中,我只是创建了一些外观、游泳和嘎嘎声都像 SerialPort 对象的东西。存根和监视就变得微不足道了。
只需使用一个将其参数存储在测试范围内的匿名函数:
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
需要创建多个具有相同参数的对象,否则将创建对象的负担交给它似乎有点傻。