Node.js Express:单元测试控制器,它调用模型mongoose模型而不真正调用数据库
我有一个由Express.js路由器调用的控制器。控制器本身调用mongoose模型。我需要在不调用数据库和独立于路由器的情况下对控制器进行单元测试 测试可能应该测试Node.js Express:单元测试控制器,它调用模型mongoose模型而不真正调用数据库,node.js,unit-testing,express,mongoose,chai,Node.js,Unit Testing,Express,Mongoose,Chai,我有一个由Express.js路由器调用的控制器。控制器本身调用mongoose模型。我需要在不调用数据库和独立于路由器的情况下对控制器进行单元测试 测试可能应该测试res.json(err)和res.json(result)响应 页面控制器: const pageModel = require('../model/page'); const pageController = { /** * Get all pages as a list * * @pa
res.json(err)
和res.json(result)
响应
页面控制器:
const pageModel = require('../model/page');
const pageController = {
/**
* Get all pages as a list
*
* @param {*} req
* @param {*} res
* @returns {json} list of pages
*/
getList(req, res) {
pageModel.find({}, (err, result)=>{
if (err) {
res.json(err);
} else {
res.json(result);
}
});
}
};
module.exports = pageController;
页面模型:
const mongoose = require('mongoose');
// Page Schema
const pageSchema = new mongoose.Schema({
title: {
type: String,
required: true
},
slug: {
type: String,
required: true,
unique: true
},
content: String,
createdIn: {
type: Date,
default: Date.now
},
updatedIn: {
type: Date,
default: Date.now
}
});
const pageModel = mongoose.model('page', pageSchema);
module.exports = pageModel;
测试:
以下是对我的问题的回答: 首先,我修改了控制器函数
getList
,以发送错误状态
getList(req, res) {
PageModel.find({}, (err, result) => {
if (err) {
res.status(500).end();
} else {
res.json(result);
}
});
}
现在,test将测试两件事情。
1-返回“页面”实例(json对象)的结果。
2-错误
说明:
1-创建sinon沙箱
let sandbox = sinon.createSandbox();
2-模拟和定义:req、res、error等
let req = {
body: {
title: 'title',
slug: 'slug',
content: 'content'
}
};
let res = {};
let expectedResult;
let error = new Error({error: 'error message here'});
3-在每次测试之前,监视res.json和res.status(错误)并创建预期结果(可选)。每次测试后,恢复沙箱
beforeEach(()=>{
res = {
json: sandbox.spy(),
status: sandbox.stub().returns({end: sandbox.spy()})
};
expectedResult = [{}, {}, {}];
});
afterEach(()=>{
sandbox.restore();
});
4-在测试中。存根mongoose.Model
非PageModel
。通过这种方式,您可以确保mongoose不会调用数据库(这很重要,因为我们不进行集成测试)。然后确保调用了PageModel
,并且控制器函数返回预期结果
it('should return result/page as json object', (done) => {
sandbox.stub(mongoose.Model, 'find').yields(null, expectedResult);
PageController.getList(req, res);
sinon.assert.calledWith(PageModel.find, {});
sinon.assert.calledWith(res.json, sinon.match.array);
done();
});
it('should return error 500', (done) => {
sandbox.stub(mongoose.Model, 'find').yields(error);
PageController.getList(req, res);
sinon.assert.calledWith(PageModel.find, {});
sinon.assert.calledWith(res.status, 500);
sinon.assert.calledOnce(res.status(500).end);
done();
});
以下是完整的代码:
const chai = require('chai');
const expect = chai.expect;
const mongoose = require('mongoose');
const PageModel = require('../../../../app/page/model/page');
const PageController = require('../../../../app/page/controller/page');
const sinon = require('sinon');
let sandbox = sinon.createSandbox();
describe('Page controller', () => {
let req = {
body: {
title: 'title',
slug: 'slug',
content: 'content'
}
};
let res = {};
let expectedResult;
let error = new Error({error: 'error message here'});
describe('getList', () => {
beforeEach(()=>{
res = {
json: sandbox.spy(),
status: sandbox.stub().returns({end: sandbox.spy()})
};
expectedResult = [{}, {}, {}];
});
afterEach(()=>{
sandbox.restore();
});
it('should return result/page as json object', (done) => {
sandbox.stub(mongoose.Model, 'find').yields(null, expectedResult);
PageController.getList(req, res);
sinon.assert.calledWith(PageModel.find, {});
sinon.assert.calledWith(res.json, sinon.match.array);
done();
});
it('should return error 500', (done) => {
sandbox.stub(mongoose.Model, 'find').yields(error);
PageController.getList(req, res);
sinon.assert.calledWith(PageModel.find, {});
sinon.assert.calledWith(res.status, 500);
sinon.assert.calledOnce(res.status(500).end);
done();
});
});
});
如果您发现此答案有改进,请随时编辑答案或编写您自己的答案
const chai = require('chai');
const expect = chai.expect;
const mongoose = require('mongoose');
const PageModel = require('../../../../app/page/model/page');
const PageController = require('../../../../app/page/controller/page');
const sinon = require('sinon');
let sandbox = sinon.createSandbox();
describe('Page controller', () => {
let req = {
body: {
title: 'title',
slug: 'slug',
content: 'content'
}
};
let res = {};
let expectedResult;
let error = new Error({error: 'error message here'});
describe('getList', () => {
beforeEach(()=>{
res = {
json: sandbox.spy(),
status: sandbox.stub().returns({end: sandbox.spy()})
};
expectedResult = [{}, {}, {}];
});
afterEach(()=>{
sandbox.restore();
});
it('should return result/page as json object', (done) => {
sandbox.stub(mongoose.Model, 'find').yields(null, expectedResult);
PageController.getList(req, res);
sinon.assert.calledWith(PageModel.find, {});
sinon.assert.calledWith(res.json, sinon.match.array);
done();
});
it('should return error 500', (done) => {
sandbox.stub(mongoose.Model, 'find').yields(error);
PageController.getList(req, res);
sinon.assert.calledWith(PageModel.find, {});
sinon.assert.calledWith(res.status, 500);
sinon.assert.calledOnce(res.status(500).end);
done();
});
});
});