使用 mocha/chai 测试多个函数回调
Test several functions callbacks with mocha/chai
我有一个全局对象,它能够为事件分配函数,例如:
obj.on('event', () => {});
在调用确切的 public API 之后,这些事件也会被触发。
现在我需要在 node.js 环境中使用 mocha.js/chai.js 和 运行 编写异步测试。
我遇到了应该同时测试两个事件订阅的情况。
所有代码都是用 TypeScript 编写的,然后转换为 JavaScript。
全局对象中的代码:
public someEvent(val1: string, val2: Object) {
// some stuff here...
this.emit('event_one', val1);
this.emit('event_two', val1, val2);
}
测试文件中的代码(我最新实现的):
// prerequisites are here...
describe('test some public API', () => {
it('should receive a string and an object', (done) => {
// counting number of succesfull calls
let steps = 0;
// function which will finish the test
const finish = () => {
if ((++steps) === 2) {
done();
}
};
// mock values
const testObj = {
val: 'test value'
};
const testStr = 'test string';
// add test handlers
obj.on('event_one', (key) => {
assert.equal(typeof key, 'string');
finish();
});
obj.on('event_two', (key, event) => {
assert.equal(typeof key, 'string');
expect(event).to.be.an.instanceOf(Object);
finish();
});
// fire the event
obj.someEvent(testStr, testObj);
});
});
所以,我的问题是 - 是否有任何内置功能可以使此测试看起来更优雅?
另一个问题是如何提供一些有意义的错误信息而不是默认的错误字符串?
Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.
感谢LostJon的评论!
我的解决方案是将 sinon.js
库添加到项目并使用 sinon.spy
.
解决方案是这样的:
import * as sinon from 'sinon';
...
// prerequisites are here...
describe('test some public API', () => {
it('should receive a string and an object', (done) => {
const spyOne = sinon.spy();
const spyTwo = sinon.spy();
// mock values
const testObj = {
val: 'test value'
};
const testStr = 'test string';
// add test handlers
obj.on('event_one', spyOne);
obj.on('event_two', spyTwo);
// fire the event
obj.someEvent(testStr, testObj);
// assert cases
assert(spyOne.calledOnce, `'event_one' should be called once`);
assert.equal(typeof spyOne.args[0][0], 'string');
assert(spyTwo.calledOnce, `'event_two' should be called once`);
assert.equal(typeof spyTwo.args[0][0], 'string');
assert.equal(typeof spyTwo.args[0][1], 'object');
});
});
我有一个全局对象,它能够为事件分配函数,例如:
obj.on('event', () => {});
在调用确切的 public API 之后,这些事件也会被触发。
现在我需要在 node.js 环境中使用 mocha.js/chai.js 和 运行 编写异步测试。
我遇到了应该同时测试两个事件订阅的情况。
所有代码都是用 TypeScript 编写的,然后转换为 JavaScript。
全局对象中的代码:
public someEvent(val1: string, val2: Object) {
// some stuff here...
this.emit('event_one', val1);
this.emit('event_two', val1, val2);
}
测试文件中的代码(我最新实现的):
// prerequisites are here...
describe('test some public API', () => {
it('should receive a string and an object', (done) => {
// counting number of succesfull calls
let steps = 0;
// function which will finish the test
const finish = () => {
if ((++steps) === 2) {
done();
}
};
// mock values
const testObj = {
val: 'test value'
};
const testStr = 'test string';
// add test handlers
obj.on('event_one', (key) => {
assert.equal(typeof key, 'string');
finish();
});
obj.on('event_two', (key, event) => {
assert.equal(typeof key, 'string');
expect(event).to.be.an.instanceOf(Object);
finish();
});
// fire the event
obj.someEvent(testStr, testObj);
});
});
所以,我的问题是 - 是否有任何内置功能可以使此测试看起来更优雅?
另一个问题是如何提供一些有意义的错误信息而不是默认的错误字符串?
Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.
感谢LostJon的评论!
我的解决方案是将 sinon.js
库添加到项目并使用 sinon.spy
.
解决方案是这样的:
import * as sinon from 'sinon';
...
// prerequisites are here...
describe('test some public API', () => {
it('should receive a string and an object', (done) => {
const spyOne = sinon.spy();
const spyTwo = sinon.spy();
// mock values
const testObj = {
val: 'test value'
};
const testStr = 'test string';
// add test handlers
obj.on('event_one', spyOne);
obj.on('event_two', spyTwo);
// fire the event
obj.someEvent(testStr, testObj);
// assert cases
assert(spyOne.calledOnce, `'event_one' should be called once`);
assert.equal(typeof spyOne.args[0][0], 'string');
assert(spyTwo.calledOnce, `'event_two' should be called once`);
assert.equal(typeof spyTwo.args[0][0], 'string');
assert.equal(typeof spyTwo.args[0][1], 'object');
});
});