javascript - 测试承诺链与异步等待 [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 中的 stub 需要返回一个被拒绝的 Promise,而不是抛出一个错误:
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
作为参数传递,这就是该方法不起作用的原因
推荐阅读
- excel - 将选项卡组合在一起时设置条件的问题
- css - :not css 选择器未按预期工作
- c++ - 关于复制构造函数的一个棘手问题
- javascript - 无法使用 jsPDF 将 HTML 转换为 PDF
- list - Flutter - 无法修改列表
- java - 如果网络可用,则从服务器获取 JSON
- oracle - Calc 脚本 Essbase 中的子字符串
- python - 如何修复 ipywidgets 中的按钮按下?
- kendo-ui - 如何将 Kendo UI Angular Chart 连接到数据源?
- oracle12c - 如何在 RHEL 64 位操作系统上安装 Oracle 客户端 32 位