javascript - 如何为带有 sinon 的函数传递假参数并期望指定的返回值
问题描述
我有两个功能,一个取决于另一个
所以例子这就是我关心的类中函数的样子,User.findOne()
并且user.update()
:
const Models = require('../models');
const { User } = Models;
class UserService {
async updateUser(data) {
const { id } = data;
const user = await User.findOne({ where: { id } })
if (user) {
return await user.update(data)
}
return null
}
}
所以我关心的两个函数是User.findOne({where: {id}})
并且user.update(data)
我正在使用带有 Postgres DB 的 Sequelize
基本上这两个是针对我的数据库的,所以findOne
需要一个 id 来从数据库中获取用户,如果成功,它将返回一个对象
user = {
id: 1
firstName: 'John'
lastName: 'Doe'
}
所以我data
在函数的参数中应该是:
data = {
id: 1
firstName: 'Jane'
lastName: 'Smith'
}
例如,我想将 John Doe 更新为 Jane Smith,并使用更新功能将其发送到数据库user.update(data)
那么我如何测试这个mocha/chai and sinon
以及我正在使用proxyquire and sequelize-test-helpers
我正在尝试使用chai and sinon mainly
我一般是新的测试。
describe('UserService Root', function () {
// this is the setup please remember mockModel.User from here and dummyUser as well as data and id
const UserModel = { // We will change the name of this object to just User soon
findOne: sinon.stub()
}
const mockModels = makeMockModels( { UserModel } );
delete Object.assign(mockModels, {['User']: mockModels['UserModel'] })['UserModel']
// UserModel is now renamed to User as that is what is inside the class function itself
const UserService = proxyquire(servicePath, {
"../models": mockModels
});
// Returns a large Object of all my Models but we will be doing mockModels.User
const userService = new UserService(); // an instance object of the class
const dummyUser = { User: { update: sinon.stub() } }
const id = 1
const data = {
id: 1,
first_name: 'Jane',
last_name: 'Smith'
}
const resetStubs = () => {
mockModels.User.findOne.resetHistory()
dummyUser.User.update.resetHistory()
}
let result;
// now that is the setup now lets describe the test
describe('User exists', () => {
before(async () => {
dummyUser.User.update.resolves(dummyUser);
// mockModels.User.findOne.r is there something I need to do here?
mockModels.User.findOne.resolves(dummyUser.User);
result = await userService.updateUser(data);
});
after(resetStubs);
it('call user.findOne() but with argument of ID how do I do that?', () => {
expect(mockModels.User.findOne).to.have.been.called; // works ok if it called with nothing
expect(mockModels.User.findOne).to.have.been.calledWith(id); // how can I call with arg?
});
it('call user.update with sinon.stub() sinon.match(data)', () => {
expect(dummyUser.User.update).to.have.been.calledWith(sinon.match(data));
});
it('returns the user', () => {
expect(result).to.deep.equal(dummyUser)
})
})
})
是的,我如何用 sinon 来称呼它User.findOne(with argument of id)
?基本上这是它阻止。
it('call user.findOne() but with argument of ID how do I do that?', () => {
expect(mockModels.User.findOne).to.have.been.called; // works ok if it called with nothing
expect(mockModels.User.findOne).to.have.been.calledWith(id); // how can I call with arg?
});
可能在之前的块中,我是否需要为它块的 calledWith(id) 进行设置才能工作?
before(async () => {
dummyUser.User.update.resolves(dummyUser);
// mockModels.User.findOne.r
mockModels.User.findOne.resolves(dummyUser.User);
result = await userService.updateUser(data);
});
解决方案
推荐阅读
- android - 滚动recylerview时如何使recylerview上方的文本滚动
- html - 如何在 HTML 中显示视频/mp2t?
- reactjs - 在 react-final-form 中使用 react-input-mask 和 antd
- c++ - 为什么我的 for 循环在我的 void 函数中不起作用
- excel - 将参数传递给数组时下标超出范围
- laravel-5 - 如何通过 API 返回 base64 视频
- python - 通过拟合模型训练模型时如何修复“未知标签类型:'未知'”
- javascript - 为什么在函数外部声明变量不起作用?
- java - 如何在 Debian 10 (Buster) 上安装 openjdk-8-jdk?
- go - 在 Golang 中将 Float64 类型打印为 int