Javascript 路由内模拟mongoose save()错误
在尝试了各种方法来测试路由的mongooseJavascript 路由内模拟mongoose save()错误,javascript,mongoose,sinon,Javascript,Mongoose,Sinon,在尝试了各种方法来测试路由的mongoosesave()抛出之后,我真的不确定该如何做。我的目标是在伊斯坦布尔实现100%的覆盖率。以下是核心设置: model.js let mongoose = require('mongoose'); let Schema = mongoose.Schema; let PasteSchema = new Schema( { message: { type: String, required: true }, tags: [String]
save()
抛出之后,我真的不确定该如何做。我的目标是在伊斯坦布尔实现100%的覆盖率。以下是核心设置:
model.js
let mongoose = require('mongoose');
let Schema = mongoose.Schema;
let PasteSchema = new Schema(
{
message: { type: String, required: true },
tags: [String],
marked: { type: Boolean, default: false },
createdAt: { type: Date, default: Date.now },
updatedAt: Date
}
);
module.exports = mongoose.model('paste', PasteSchema);
controller.js
let Paste = require('./model');
// Other stuff
// I use a bit non-standard DELETE /pastes/:id for this
const markPaste = (req, res) => {
Paste.findById({ _id: req.params.id }, (err, paste) => {
if (!paste) {
res.status(404).json({ result: 'Paste not found' });
return;
}
paste.marked = true;
paste.updatedAt = new Date();
paste.save((err) => {
err
? res.status(400).json({ result: err })
: res.json({ result: 'Paste marked' });
});
});
}
module.exports = {
markPaste,
// Other stuff
}
routes.js
const express = require('express');
const app = express();
const pastes = require('./apps/pastes/controller'); // The file above
app.route('/pastes/:id')
.delete(pastes.markPaste);
module.exports = app;
在下面的测试中,我想模拟在上面的paste.save((err)=>{
中抛出的错误
process.env.NODE_ENV = 'test';
let mongoose = require('mongoose');
let Paste = require('../apps/pastes/model');
let server = require('../index');
let chai = require('chai');
chai.use(require('chai-http'));
chai.use(require('chai-date-string'));
let expect = chai.expect;
let sinon = require('sinon');
let sandbox = sinon.createSandbox();
let pastes = require('../apps/pastes/controller');
let httpMocks = require('node-mocks-http');
// Other tests
然后,我要测试的测试路径中的save()
错误:
it('should handle an error during the save in the endpoint', (done) => {
// Create a paste to be deleted
const pasteItem = new Paste({ message: 'Test 1', tags: ['integration', 'test'] });
pasteItem.save()
.then((paste) => {
// Attempt code from below goes here
})
.catch((err) => {
console.log('Should not go here');
});
done();
});
我在各种堆栈问题或在线问题中都没有找到任何明确的参考,所以我是这样做的: 秘密在于使用
sinon
沙箱,它甚至在测试期间应用于路由上下文中。以下是工作测试:
it('should handle an error during the save in the endpoint', (done) => {
const pasteItem = new Paste({ message: 'Test 1', tags: ['integration', 'test'] });
pasteItem.save()
.then((paste) => {
// the sandbox is defined in the imports
// This forces calling save() to raise an error
sandbox.stub(mongoose.Model.prototype, 'save').yields({ error: 'MongoError' });
chai.request(server)
.delete('/pastes/' + paste._id)
.end((err, res) => {
// It applies within the route handling, so we get the expected 400
expect(res).to.have.status(400);
done();
});
})
.catch((err) => {
console.log('Should not go here');
});
});
如果您在沙箱之外调用它,您将破坏所有使用sinon
的后续测试
// This would break things unintendedly
sinon.stub(mongoose.Model.prototype, 'save').yields({ error: 'MongoError' });
// This only breaks things (on purpose) in the test we want it to break in:
sandbox.stub(mongoose.Model.prototype, 'save').yields({ error: 'MongoError' });
如果在特定的sandbox
实例中有多个对象,当然可以在测试用例之后使用sandbox.restore();
恢复测试中的“未中断”状态
->
耶
=============================== Coverage summary ===============================
Statements : 100% ( 60/60 )
Branches : 100% ( 14/14 )
Functions : 100% ( 0/0 )
Lines : 100% ( 57/57 )
================================================================================