gpt4 book ai didi

javascript - Node : How to assert if event callback function was called using sinon

转载 作者:搜寻专家 更新时间:2023-11-01 00:47:29 24 4
gpt4 key购买 nike

如何测试事件监听器的回调函数是否被调用?例如,我有以下代码,其中 app.js 通过 init.js Controller 初始化应用程序。

main.js 文件有一个类扩展和事件发射器,使对象成为事件发射器。

app.js

const initController = require('./init');
async function init() {
initController.startMain();
}
init();

main.js

const events = require('events'),
ui = require('./ui');

module.exports.getMain = function () {
class Main extends events.EventEmitter {
constructor() {
super();
this.status = null;
}
}
return new Main();
};

module.exports.init = () => {
const main = this.getMain();
ui.init(main);
this.start(main);
}

module.exports.start = (main) => {
ui.start(main);
main.emit('http-init');
main.emit('http-success');
main.emit('http-error');
};

ui.js

function init(main) {
main.on('http-init', onHttpInit.bind(this));
main.on('http-success', onHttpSuccess.bind(this));
main.on('http-error', onHttpError.bind(this));
main.once('app-ready', onAppReady.bind(this));
};

function start (main) {};

function onAppReady() {
console.log('APP READY');
};

function onHttpInit() {
console.log('HTTP INIT SEQUENCE');
};

function onHttpError(error) {
console.log('HTTP ERROR SEQUENCE');
};

function onHttpSuccess() {
console.log('HTTP SUCCESS SEQUENCE');
};

module.exports = exports = {
init,
start,
onHttpInit,
onHttpError,
onHttpSuccess,
};

init.js

exports.startMain = () => {

console.log('Start application');

// Load application modules
const main = require('./main');

// Start the application
main.init();
};

因此,当我运行命令 node app.js 时,我看到了以下输出

开始申请HTTP 初始化序列HTTP 成功序列HTTP 错误序列

这意味着监听器处于事件状态并且调用了函数。

ui.tests.js

const sinon = require('sinon'),
main = require('../main').getMain(),
proxyquire = require('proxyquire').noPreserveCache().noCallThru();

describe('UI Tests', () => {
const sandbox = sinon.createSandbox();
let controller = null;
before(() => {
controller = proxyquire('../ui', {});
})
describe('Testing Eventlisteners', ()=> {
afterEach(() => {
main.removeAllListeners();
});
const eventMap = new Map([
[ 'http-init', 'onHttpInit' ],
[ 'http-success', 'onHttpSuccess' ],
[ 'http-error', 'onHttpError']
]);
eventMap.forEach((value, key) => {
it(`should register an eventlistener on '${key}' to ${value}`, () => {
const stub = sinon.stub(controller, value);
controller.init(main);
main.emit(key);
sinon.assert.called(stub);
})
})
})
})

然而,当我运行上面的测试时,即使我得到了输出,即调用了函数,但是,sinon assert 总是失败,说下面的内容:

  UI Tests
Testing Eventlisteners
HTTP INIT SEQUENCE
1) should register an eventlistener on 'http-init' to onHttpInit
HTTP SUCCESS SEQUENCE
2) should register an eventlistener on 'http-success' to onHttpSuccess
HTTP ERROR SEQUENCE
3) should register an eventlistener on 'http-error' to onHttpError


0 passing (16ms)
3 failing

1) UI Tests
Testing Eventlisteners
should register an eventlistener on 'http-init' to onHttpInit:
AssertError: expected onHttpInit to have been called at least once but was never called
at Object.fail (node_modules/sinon/lib/sinon/assert.js:106:21)
at failAssertion (node_modules/sinon/lib/sinon/assert.js:65:16)
at Object.assert.(anonymous function) [as called] (node_modules/sinon/lib/sinon/assert.js:91:13)
at Context.it (test/ui.tests.js:25:30)
2) UI Tests
Testing Eventlisteners
should register an eventlistener on 'http-success' to onHttpSuccess:
AssertError: expected onHttpSuccess to have been called at least once but was never called
at Object.fail (node_modules/sinon/lib/sinon/assert.js:106:21)
at failAssertion (node_modules/sinon/lib/sinon/assert.js:65:16)
at Object.assert.(anonymous function) [as called] (node_modules/sinon/lib/sinon/assert.js:91:13)
at Context.it (test/ui.tests.js:25:30)

3) UI Tests
Testing Eventlisteners
should register an eventlistener on 'http-error' to onHttpError:
AssertError: expected onHttpError to have been called at least once but was never called
at Object.fail (node_modules/sinon/lib/sinon/assert.js:106:21)
at failAssertion (node_modules/sinon/lib/sinon/assert.js:65:16)
at Object.assert.(anonymous function) [as called] (node_modules/sinon/lib/sinon/assert.js:91:13)
at Context.it (test/ui.tests.js:25:30)

我不知道为什么即使该函数至少被调用一次,测试也会失败,这可以从输出 HTTP INIT SEQUENCEHTTP SUCCESS SEQUENCEHTTP 错误序列 当我运行测试时。

我试着做 stub.should.have.been.called;。有了这个测试通过,但是,它并没有真正通过 stub.should.have.been.called;stub.should.not.have.been.called; 不管怎样都通过测试,而不是后者未通过测试。

有人知道这个测试失败的原因吗?感谢您的帮助。

最佳答案

您运行 const stub = sinon.stub(controller, value); 来 stub 由您的 ui 模块导出的值。这确实改变了模块导出的值,但问题出在 ui 模块中的这段代码:

function init(main) {
main.on('http-init', onHttpInit.bind(this));
main.on('http-success', onHttpSuccess.bind(this));
main.on('http-error', onHttpError.bind(this));
main.once('app-ready', onAppReady.bind(this));
}

从这段代码的 Angular 来看,module.exports 被你的调用sinon.stub(controller, value)改变了,但是这不会更改上面代码中符号 onHttpInitonHttpSuccess 等符号的值,因为这些符号是 ui 范围内的局部符号模块。您可以随心所欲地改变 module.exports:它仍然对上面的代码没有影响。

您可以将代码更改为:

function init(main) {
main.on('http-init', exports.onHttpInit.bind(this));
main.on('http-success', exports.onHttpSuccess.bind(this));
main.on('http-error', exports.onHttpError.bind(this));
main.once('app-ready', exports.onAppReady.bind(this));
}

您可以直接使用 exports,因为您为 module.exportsexports 分配了相同的值,其中 module.exports =导出 = ...

此更改应该可以解决您遇到的直接问题。但是,我会在这里修改测试方法。您的测试标题为 should register an eventlistener on '${key}' to ${value} 但实际上您正在测试的不仅仅是事件监听器已注册,而且事件传播有效。实际上,您正在测试 EventEmitter 负责提供的功能。我将更改测试以对 main 对象的 on 方法进行 stub ,并验证是否已使用适当的值调用它。然后测试将测试它实际宣传的内容。

关于javascript - Node : How to assert if event callback function was called using sinon,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57657332/

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