[英]Unit testing async/await javascript with mocha and chai
[英]Testing promise chains vs async await [mocha/chai/sinon]
所以我是测试新手,并且已经设置了一个模拟数据库调用失败的方法的基本测试(对不起,如果我的术语不太正确)
我正在使用 sequelize,所以Job
是一个模型,而findAndCountAll
是一个相关的方法。
it('Should throw a 500 error if accessing the DB fails', () => {
sinon.stub(Job, 'findAndCountAll');
Job.findAndCountAll.throws();
const req = {
query: {
index: 0,
limit: 10,
orderField: 'createdAt',
order: 'DESC'
}
};
adminController.getJobs(req, {}, () => {}).then(result => {
expect(result).to.be.an('error');
expect(result).to.have.property('statusCode', 500);
done();
})
Job.findAndCountAll.restore();
})
我的问题是我的大部分代码都是使用承诺链编写的:
exports.getJobs = (req, res, next) => {
const index = req.query.index || 0;
const limit = req.query.limit || 10;
const orderField = req.query.orderField || 'createdAt';
const order = req.query.orderDirection || 'DESC';
Job.findAndCountAll({
// ...arguments
})
.then(results => {
res.status(200).json({ jobs: results.rows, total: results.count });
return // Attempted to add a return statement to enter the .then() block in the test
})
.catch(err => {
if(!err.statusCode) err.statusCode = 500;
next(err);
return err; // Attempted to return the error to enter the .then() block in the test
});
这不起作用,我的(不必要的)返回语句也无济于事。
但是,使用async await
重写方法确实有效(见下文)。 但是我想避免重写我的所有代码,如果能理解这里的区别会很好。
我最好的猜测是,与其让 sinon 存根抛出错误,不如让它拒绝承诺? 我只是不完全确定这是否正确,或者如何实现它。 我有点绊倒文档并不真正知道
任何帮助表示赞赏,
谢谢,
缺口
exports.getJobs = async(req, res, next) => {
const index = req.query.index || 0;
const limit = req.query.limit || 10;
const orderField = req.query.orderField || 'createdAt';
const order = req.query.orderDirection || 'DESC';
try {
const results = await Job.findAndCountAll({ //...params });
// ...
res.status(200).json({ jobs: results.rows, total: results.count });
return;
} catch(err) {
if(!err.statusCode) err.statusCode = 500;
next(err);
return err;
}
};
所以我想我找到了答案:
sinon 中的存根需要返回一个被拒绝的承诺,而不是抛出一个错误:
sinon.stub(Job, 'findAndCountAll');
Job.findAndCountAll.rejects();
Afaik 这是因为你不能真正在异步代码中抛出错误。
您正在测试的方法中的 Promise 链(在我的例子中是“getJobs”),需要返回该承诺。
所以代替
Job.findAndCountAll({
// ...arguments
})
.then(results => {
res.status(200).json({...});
return;
})
.catch(err => {
if(!err.statusCode) err.statusCode = 500;
next(err);
return err;
});
采用
const results = Job.findAndCountAll({
// ...arguments
})
.then(results => {
res.status(200).json({...});
return;
})
.catch(err => {
if(!err.statusCode) err.statusCode = 500;
next(err);
return err;
});
return results;
此外,测试中的异步函数需要返回或等待,以便 mocha 知道等待。 使用done()
对我不起作用:
const result = await adminController.getJobs(req, {}, () => {});
expect(result).to.be.an('error');
expect(result).to.have.property('statusCode', 500);
Job.findAndCountAll.restore();
希望能帮助某人
**编辑:如下所述,我忘记将done
作为参数传递,这就是该方法不起作用的原因
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.