return 承诺使用 Mocha 对多个异步调用进行单元测试
Unit testing multiple asynchronous calls that return promises with Mocha
我正在尝试了解如何最好地对我的异步 CommonJS 模块进行单元测试。在处理多个链式承诺时,我很难理解最佳实践。
假设我定义了以下模块:
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)
})
}
并且我有以下规范文件试图测试是否进行了正确的调用。
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 解决这个问题,但我想看看其他人如何更优雅地解决这个问题。
我曾尝试将 chai-as-promised 添加到组合中,但运气不佳。我当前的设置包括 sinon、chai、sinon-as-promised 和 sinon-chai。
谢谢
您应该使用 module()
return 是一个承诺这一事实,因此您可以将另一个 .then()
添加到链中,您可以在其中断言参数(因为此时前一个已调用 .then()
个步骤,包括对 api.post()
) 的调用。
并且由于 Mocha 支持承诺,您可以 return 生成的承诺,而不必处理 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')
});
})
我正在尝试了解如何最好地对我的异步 CommonJS 模块进行单元测试。在处理多个链式承诺时,我很难理解最佳实践。
假设我定义了以下模块:
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)
})
}
并且我有以下规范文件试图测试是否进行了正确的调用。
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 解决这个问题,但我想看看其他人如何更优雅地解决这个问题。
我曾尝试将 chai-as-promised 添加到组合中,但运气不佳。我当前的设置包括 sinon、chai、sinon-as-promised 和 sinon-chai。
谢谢
您应该使用 module()
return 是一个承诺这一事实,因此您可以将另一个 .then()
添加到链中,您可以在其中断言参数(因为此时前一个已调用 .then()
个步骤,包括对 api.post()
) 的调用。
并且由于 Mocha 支持承诺,您可以 return 生成的承诺,而不必处理 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')
});
})