unit testing用Mocha返回承诺的多个asynchronous调用
我想了解如何最好的unit testing我的asynchronousCommonJS模块。 在处理多重链式承诺时,我正在努力理解最佳实践。
让我们假设我有以下模块定义:
module.exports = function(api, logger) { return api.get('/foo') .then(res => { return api.post('/bar/' + res.id) }) .then(res => { logger.log(res) }) .catch(err => { logger.error(err) }) }
我有以下spec文件试图testing正确的调用。
var module = require('./module') describe('module()', function() { var api; var logger; var getStub; var postStub; beforeEach(function() { getStub = sinon.stub(); postStub = sinon.stub(); api = { get: getStub.resolves({id: '123'), post: postStub.resolves() } logger = { log: sinon.spy(), error: sinon.spy() } }) afterEach(function() { getStub.restore(); postStub.restore(); }); it('should call get and post', function(done) { module(api, logger) // System under test expect(getStub).to.have.been.calledWith('/foo') expect(postStub).to.have.been.calledWith('/bar/123') done() }) })
这不起作用。 第一个断言正确传递,但是第二个断言失败了,大概这个承诺在执行时没有解决。
我可以使用process.nextTick或setTimeout来解决这个问题,但我想看看其他人如何更好地解决这个问题。
我已经尝试过将运气好的join到组合中。 我目前的设置包括,sinon,chai,sinon-as-promise和sinon-chai。
谢谢
你应该使用这个事实,即module()
返回一个promise,所以你可以添加另外一个.then()
到你可以断言参数的链(因为在那个时候之前的.then()
步骤已经被调用,包括调用到api.post()
)。
而且,由于摩卡支持承诺,您可以返回所产生的承诺,而不必处理done
:
it('should call get and post', function() { return module(api, logger).then(() => { expect(getStub).to.have.been.calledWith('/foo') expect(postStub).to.have.been.calledWith('/bar/123') }); })