gpt4 book ai didi

node.js - 在我的测试中,使用 stub 函数未捕获事件

转载 作者:太空宇宙 更新时间:2023-11-03 23:43:39 25 4
gpt4 key购买 nike

我遇到了一个我不明白的问题。我的测试中没有捕获我发出的事件。以下是以下代码 (event.js):

var util = require('util'),
proc = require('child_process'),
EventEmitter = require('events').EventEmitter;

var Event = function() {
var _self = this;
proc.exec('ls -l', function(error, stdout, stderr) {
_self.emit('test');
console.log('emitted');
});
};
util.inherits(Event, EventEmitter);

module.exports = Event;

以及相应的测试:

var proc = require('child_process'),
sinon = require('sinon'),
chai = require('chai'),
expect = chai.expect,
Event = require('./event'),
myEvent, exec;

var execStub = function() {
var _self = this;
return sinon.stub(proc, 'exec', function(cmd, callback) {
_self.cmd = cmd;
console.log(cmd);
callback();
});
};

describe('Event', function() {
beforeEach(function(){
exec = execStub();
});

afterEach(function(){
exec.restore();
});

it('Event should be fired', function(done) {
myEvent = new Event();
myEvent.on('test', function() {
expect(exec.cmd).to.equal('ls -l');
done();
});
});
});

目前,这是我所看到的:

  • console.log('emissed'); 发生以来,该事件实际上是在测试期间发出的
  • 由于 console.log(cmd); 发生,exec 函数实际上已被 stub

但是测试因超时而失败,并显示错误消息:

~ % mocha --timeout 15000 -R spec event.test.js


Event
◦ Event should be fired: ls -l
emitted
1) Event should be fired


0 passing (15 seconds)
1 failing

1) Event Event should be fired:
Error: timeout of 15000ms exceeded
at null.<anonymous> (/usr/lib/node_modules/mocha/lib/runnable.js:165:14)
at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)

如果我从测试中删除 stub ,则测试运行正常。如果我增加超时,我仍然遇到同样的问题。

知道我做错了什么吗?

问候

最佳答案

您的 stub 更改了 process.exec() 的同步/异步方面。

内部 Node 的实现保证回调始终在事件循环的下一轮中运行:

myEvent = new Event(); // calls process.exec
myEvent.on('test', function() {
expect(exec.cmd).to.equal('ls -l');
done();
});
// process.exec callback will be called after all this code is executed

您的 stub 正在立即调用回调:

myEvent = new Event(); // calls process.exec
// process.exec callback is called immediately
// test event is emitted before listeners are attached
myEvent.on('test', function() {
expect(exec.cmd).to.equal('ls -l');
done();
});

解决方案是process.nextTick():

var execStub = function() {
var _self = this;
return sinon.stub(proc, 'exec', function(cmd, callback) {
_self.cmd = cmd;
console.log(cmd);
process.nextTick(callback);
});
};

您的测试还有另一个问题:exec stub 回调中的 _self 引用了全局对象,您正在将该值保存到 global.cmd。您希望稍后在测试中获得 exec.cmd 中的值。

这是 execStub 的最终和修复版本:

var execStub = function() {
var _self = sinon.stub(proc, 'exec', function(cmd, callback) {
_self.cmd = cmd;
console.log(cmd);
process.nextTick(callback);
});
return _self;
};

查看此post有关回调异步性的更多信息。

关于node.js - 在我的测试中,使用 stub 函数未捕获事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18142809/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com