基本上,我正在测试一个StreamReader,它在POST请求执行时发出事件,导致流阅读器解析并发出data
事件。
我正在使用mocha
,chai
(使用chai-http
)和sinon.spy
来测试调用REST API的类接收响应的特定方案然后在响应处理程序中向其他事件侦听器发出“data”事件。
我已经阅读了很多关于使用带有Promise的chai-http
来测试带有assert和expect的响应。为此,我尝试使用相同的模式来测试数据事件,但即使使用Promises,在完成Promise并且测试用例完成之后,才会触发sinon.spy
侦听器。
关于测试案例......
第一次尝试 - 使用sinon.spy
作为回调
it('should emit a "data" event when one record is POSTed and parsed', function() {
let spy = sinon.spy();
let reader = new Reader(sync_query);
reader.on('data', spy);
return chai.request(SYNC_URI)
.post('/db/_bulk_docs')
.set("Content-type", "application/json")
.send({ "docs": [{"user": "tempura"}, {"user": "shrimp"}] })
.then(function(response){
expect(response.body).to.have.lengthOf(2);
sinon.assert.calledOnce(spy);
// Executes too soon. I can see the event in another listener's logs.
// I'd like the test to run until the spy fires or a timeout occurs.
})
.catch(function(error) {
throw error;
});
// EXITS BEFORE EVENTS are triggered?
});
编辑1 - 使用标准回调
it('should emit a "data" event when one record is POSTed and parsed', function() {
let reader = new CouchReader(sync_query);
// This works perfectly to catch when the event is fired but...
reader.on('data', function(evt) {
try {
assert.isOk(evt);
done();
} catch (error) {
done(error);
}
});
chai.request(SYNC_GATEWAY_URI)
.post('/db/_bulk_docs')
.set("Content-type", "application/json")
.send({ "docs": [{"user": "toszter"}, {"user": "bartacus"}] })
.then(function(response){
// ...the next expect doesn't get caught when thrown.
// Can't return chai.request as a promise b/c of the callback.
expect(response.body).to.have.lengthOf(3);
})
.catch(function(error) {
throw error;
});
this.timeout(4000);
});
我想知道......
chai.request
中的断言与回调中的断言正交,但两者都会影响测试的结果,或者.. /db/_bulk_docs
请求?您的投票可能是选项2,是吗?
我尝试过done
(正确吗?),然后setImmediate()
,现在正在考虑process.nextTick()
而使用非Promise版本,但首先,我作为其他有更多使用经验的人摩卡(等)测试类似的场景:
request
模块吗?请原谅我,如果那里有重复,但在我的搜索中,我找不到一个......
答案 0 :(得分:0)
这可能不是最好的答案,但我已经找到了解决方案。我的OP是集成测试的问题,不仅仅是一个单元。我正在尝试测试(这些单位):
data
事件。data
事件与我发送给API请求的输入一起打包。这是一个太多来放一个测试用例和一个宝贵的教训。
相反,我只使用每个需要的代码独立测试每个案例。
describe.only('#message', function() {
it('should emit a "bdata" event when message is called.', function() {
let spy = sinon.spy();
let reader = new Reader(sync_query);
reader.on('data', spy);
reader.message({obj: {last_seq: 1}});
sinon.assert.calledOnce(spy); // Hooray, it works!
});
});
但是,如果我真的在一次尖锐的斧头之后进行端到端的集成测试,那么为什么不呢?正如他们在Pushkar所说的那样。
describe('#message event', function() {
it('should emit a "data" event when Server saves data via Gateway APIs', function(done) {
let reader = new CouchReader(sync_query);
reader.on('data', function(evt) { // <-- I could make this a spy()
try {
assert.isOk(evt);
// assert the event payload here
done();
} catch (error) {
done(error);
}
});
chai.request(SYNC_GATEWAY_URI)
.post('/db/_bulk_docs')
.set("Content-type", "application/json")
.send({ "docs": [{"user": "toszter"}, {"user": "bartacus"}] })
.catch(function(error) {
throw error;
});
this.timeout(4000);
});
});
...在这种情况下,如果它超时,那么我已经丢失了我的球拍并开始了新的任务。