javascript - Jest mock 并不总是适用于异步测试
问题描述
我有一个函数,我想用 Jest 测试它。
function handleRegister() {
return (req, res) => {
try {
const credentials = {
login: req.body.email,
password: req.body.password
}
res.status(201).send({ msg: 'User registration achieved successfully' }) //LINE 10
res.status(201).send({ msg: 'User registration achieved successfully' }) //LINE 11
auth.register(credentials, (err, result) => {
console.log('register', auth.getUsers())
if (result.status === 201) {
res.status(201).send({ msg: 'User registration achieved successfully' }) //LINE 17
console.log('User registration achieved successfully')
}
})
} catch(err) {
}
}}
我的测试代码是:
test('should return status 201 and msg', done => {
try {
const fun = handlers.handleRegister()
const res = {
status: jest.fn().mockReturnThis(),
send: function () {
done()
}
}
fun({ body: { email: 'a', password: 'a' } }, res)
expect(res.status).toBeCalledWith(201)
} catch(err) {
done(err)
}
})
问题是函数 handlerRegister 第 10 行和第 11 行已正确执行,但在第 17 行出现错误:
/home/anna/Desktop/dev/exampleShop/backend/handlers.js:149
res.status(201).send({
^
TypeError: Cannot read property 'send' of undefined
at auth.register (/home/anna/Desktop/dev/exampleShop/backend/handlers.js:149:26)
at addAccountToDB (/home/anna/Desktop/dev/exampleShop/backend/auth.js:69:7)
at addAccountToDB (/home/anna/Desktop/dev/exampleShop/backend/auth.js:81:3)
at hashPassword (/home/anna/Desktop/dev/exampleShop/backend/auth.js:68:5)
at AsyncWrap.crypto.scrypt (/home/anna/Desktop/dev/exampleShop/backend/auth.js:87:5)
at AsyncWrap.wrap.ondone (internal/crypto/scrypt.js:43:48)
如果我使用 js,而不是属性 res 中的模拟,例如:
const res = {
status: function(){return this},
send: function () {
done()
}
}
}
那么我没有这个错误。
有人可以解释我有什么问题吗?
解决方案
存在范围界定问题。res
没有在你调用的地方定义res.send()
,因为res
是在try
块内定义的。
将您的期望语句移到try
下面的类似内容中,或者在与您的语句res
相同的范围内定义。expect
您也不能调用.toBeCalledWith
不是模拟函数的函数。所以请注意,我已经定义res.send
为一个模拟函数,而是done()
在期望语句的末尾调用。
test('should return status 201 and msg', done => {
try {
const fun = handlers.handleRegister()
// res only exists inside of the `try`
const res = {
status: jest.fn().mockReturnThis(),
send: jest.fn() // << is now a mock function
}
fun({ body: { email: 'a', password: 'a' } }, res)
expect(res.status).toBeCalledWith(201)
// here `res.send` is now defined, and you can use `toBeCalledWith`
expect(res.send).toBeCalledWith({ msg: 'User registration achieved successfully' })
done();
} catch(err) {
done(err)
}
})
推荐阅读
- azure - 如何使用 Docker-compose 文件在 Azure WebApp 上部署 Grafana?
- python - 填写第一个卡号字段后,我在页面上找不到任何 iframe。如何解决这个问题
- c# - Winforms:改变图表的属性
- javascript - 在 nodejs 脚本中存储和显示返回的 JSON 对象
- c# - 未调用列表视图中的 xamarin 项目单击
- typo3 - 添加 IRRE 记录会停用强制验证
- java - 您可以使用 Scene Builder 在 JavaFX 界面中加载 .docx 文件吗?
- javascript - 如何在 gatsby 中使用 material-ui 主题和 redux
- python-3.x - 我正在创建一个带有浮点数的列表,但出现此错误
- linux - 自行擦除的mongodb数据库问题