我正在尝试编写一个基本的单元测试来处理下面的函数,但无法使其工作。如何测试返回正确的npm-express响应?
我已经查看了Using Sinon to stub chained Mongoose calls,https://codeutopia.net/blog/2016/06/10/mongoose-models-and-unit-tests-the-definitive-guide/和Unit Test with Mongoose,但仍然无法弄明白。我当前的最佳猜测以及由此产生的错误低于要测试的功能。如果可能的话,我不想使用任何东西,除了Mocha,Sinon和Chai.expect(即不是sinon-mongoose,chai-as-expected等)。任何其他建议,比如我可以/应该在这里测试的其他建议,是受欢迎的。谢谢!
要测试的功能:
function testGetOneProfile(user_id, res) {
Profiles
.findOne(user_id)
.exec()
.then( (profile) => {
let name = profile.user_name,
skills = profile.skills.join('\n'),
data = { 'name': name, 'skills': skills };
return res
.status(200)
.send(data);
})
.catch( (err) => console.log('Error:', err));
}
我目前的最佳猜测单元测试:
const mongoose = require('mongoose'),
sinon = require('sinon'),
chai = require('chai'),
expect = chai.expect,
Profile = require('../models/profileModel'),
foo = require('../bin/foo');
mongoose.Promise = global.Promise;
describe('testGetOneProfile', function() {
beforeEach( function() {
sinon.stub(Profile, 'findOne');
});
afterEach( function() {
Profile.findOne.restore();
});
it('should send a response', function() {
let mock_user_id = 'U5YEHNYBS';
let expectedModel = {
user_id: 'U5YEHNYBS',
user_name: 'gus',
skills: [ 'JavaScript', 'Node.js', 'Java', 'Fitness', 'Riding', 'backend']
};
let expectedResponse = {
'name': 'gus',
'skills': 'JavaScript, Node.js, Java, Fitness, Riding, backend'
};
let res = {
send: sinon.stub(),
status: sinon.stub()
};
sinon.stub(mongoose.Query.prototype, 'exec').yields(null, expectedResponse);
Profile.findOne.returns(expectedModel);
foo.testGetOneProfile(mock_user_id, res);
sinon.assert.calledWith(res.send, expectedResponse);
});
});
测试信息:
1) testGetOneProfile should send a response:
TypeError: Profiles.findOne(...).exec is not a function
at Object.testGetOneProfile (bin\foo.js:187:10)
at Context.<anonymous> (test\foo.test.js:99:12)
答案 0 :(得分:3)
这是一个棘手的场景。这里的问题是测试中的findOne存根返回模型对象 - 相反,它需要返回一个包含属性exec
的对象,而属性const findOneResult = {
exec: sinon.stub().resolves(expectedModel)
}
Profile.findOne.returns(findOneResult);
又是一个最终解析为模型值的promise-returns函数。 ..是的,如上所述,它有点棘手:)
这样的事情:
status
您还需要让响应对象上的send
函数返回包含//if we set up the stub to return the res object
//it returns the necessary func
res.status.returns(res);
函数的对象
{{1}}
我认为你不应该在测试中改变任何其他东西,它可能会那样工作。请注意,你可以使用sinon 2.0或更新版本来解析函数存在于存根(或者你可以使用sinon-as-promised with sinon 1.x)
这篇文章详细介绍了如何处理这样的复杂对象: https://codeutopia.net/blog/2016/05/23/sinon-js-quick-tip-how-to-stubmock-complex-objects-such-as-dom-objects/