我有一个看起来像这样的方法getTask()
:
const Task = require('./model');
const User = require('../users/model')
module.exports = async function getTask (key) {
const task = await Task.findOne({key}).exec()
const user = await User.findById(task.author).exec()
task.author = user
return task
};
[基本上,我只是按key
找到任务,在users
集合中找到作者,将它们组合在一起,然后在端点中这样称呼它:
app.get('/task/:key', async (req, res, next) => {
const task = await getTask(req.params.key)
res.status(200).json(task)
})
这就是我尝试测试此方法的方式:
const { expect } = require('chai')
const sinon = require('sinon')
const sinonTest = require('sinon-test')
const Task = require('./model');
const User = require('../users/model')
const getTask = require('./services')
const test = sinonTest(sinon);
describe('Task CRUD operations', () => {
it('should find task and user and return together', test(async function() {
const mockUser = new User({ id: '5e684ebacb19f70020661f44', username: 'testuser' });
const mockTask = new Task({ id: '5e684ececb19f70020661f45', key: 'TEST-1', author: mockUser });
const mockTaskFindOne = {
exec: function () {
return mockTask
}
};
const mockUserFindById = {
exec: function () {
return mockUser
}
};
this.stub(Task, 'findOne').returns(mockTaskFindOne)
this.stub(User, 'findById').returns(mockUserFindById)
const task = getTask('TEST-1')
sinon.assert.calledWith(Task.findOne, { key: 'TEST-1' })
sinon.assert.calledWith(User.findById, '5e684ebacb19f70020661f44')
// TODO: assert returned task is what I expect
}));
});
所以我想断言Task.findOne()
和User.findById()
是用正确的参数调用的,最后验证返回的task
数据。
现在唯一的最后一行在我断言User.findById
被调用的地方不起作用:
Task CRUD operations
spec.js:54
1) should find task and user and return together
spec.js:88
0 passing (17ms)
base.js:319
1 failing
base.js:332
1) Task CRUD operations
should find task and user and return together:
AssertError: expected findById to be called with arguments
at Object.fail (node_modules/sinon/lib/sinon/assert.js:107:21)
at failAssertion (node_modules/sinon/lib/sinon/assert.js:66:16)
at Object.assert.<computed> [as calledWith] (node_modules/sinon/lib/sinon/assert.js:92:13)
at Context.<anonymous> (tasks/services.test.js:36:22)
at callSandboxedFn (node_modules/sinon-test/lib/test.js:103:25)
at Context.sinonSandboxedTest (node_modules/sinon-test/lib/test.js:131:26)
at processImmediate (internal/timers.js:445:21)
我知道它与Promises等有关,但我是一个完全的新手。
我在做什么错?
我的Task
模型:
const mongoose = require('mongoose');
let TaskSchema = new mongoose.Schema({
key: String,
author: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
});
module.exports = mongoose.model('Task', TaskSchema);
我的User
模型:
const mongoose = require('mongoose');
const passportLocalMongoose = require('passport-local-mongoose');
let UserSchema = new mongoose.Schema({
username: String,
password: String
});
UserSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model('User', UserSchema);
基于getTask()
函数,用task.author调用User.findById()
。这表示sinon.assert.calledWith(User.findById, mockUser)
。而已。
我创建了这个没有sinon-test的简单示例,以确保所做的更改正确运行。
// @file stackoverflow.spec.js
const { expect } = require('chai');
const sinon = require('sinon');
const Task = require('./task.model');
const User = require('./user.model');
const getTask = require('./services');
describe('Task CRUD operations', function () {
const sandbox = sinon.createSandbox();
it('should find task and user and return together', async function () {
const mockUser = { id: '5e684ebacb19f70020661f44', username: 'testuser' };
const mockTask = { id: '5e684ececb19f70020661f45', key: 'TEST-1', author: mockUser };
const mockTaskFindOne = sandbox.stub(Task, 'findOne');
mockTaskFindOne.returns({
exec: () => mockTask,
});
const mockUserFindById = sandbox.stub(User, 'findById');
mockUserFindById.returns({
exec: () => mockUser,
});
const task = await getTask('TEST-1');
// Verify task.
expect(task).to.deep.equal(mockTask);
// Verify stub.
expect(mockTaskFindOne.calledOnce).to.equal(true);
expect(mockTaskFindOne.args[0][0]).to.deep.equal({ key: 'TEST-1' });
// This is the same with above.
expect(mockTaskFindOne.calledWith({ key: 'TEST-1' })).to.equal(true);
expect(mockUserFindById.calledOnce).to.equal(true);
expect(mockUserFindById.args[0][0]).to.deep.equal(mockUser);
// This is the same with above.
expect(mockUserFindById.calledWith(mockUser)).to.equal(true);
// Restore stub.
mockTaskFindOne.restore();
mockUserFindById.restore();
// Restore sandbox.
sandbox.restore();
});
});
通过摩卡运行时通过。
$ mocha stackoverflow.spec.js
Task CRUD operations
✓ should find task and user and return together
1 passing (11ms)
$
希望这会有所帮助。