使用Jest+Supertest测试Express应用删除接口失败问题排查
Express账号删除测试失败问题排查与解决
问题描述
测试Express应用的登录和账号删除功能时,登录的POST/GET方法运行正常,但执行删除测试后查询数据库,返回的仍是登录所用的账号信息而非预期的null。确认数据库文档已被成功删除,但查询结果不符合预期。已尝试以下方案但未解决:
- 切换Supertest的
DEL和DELETE请求方法 - 将数据库从MongoDB Atlas更换为本地实例
- 降级Jest、Supertest、MongoDB和Mongoose版本
问题原因
核心问题在于删除路由中的异步操作未正确等待完成:
req.user.remove() // 缺少await,删除操作还未完成就已响应请求
remove()是异步方法,没有await的情况下,代码会直接执行res.send(req.user),此时数据库的删除操作可能还未完成,导致测试中后续的查询仍能获取到未被删除的文档快照。此外,Mongoose新版本中remove()方法已被标记为弃用,推荐使用更明确的删除方法。
解决方案
修改删除路由代码
将删除操作改为异步等待完成,可选择以下两种方案:
方案1:修复remove()的异步等待
router.delete('/users/me', auth, async(req, res)=>{ try{ await req.user.remove() // 添加await,确保删除操作完成后再响应 res.send(req.user) }catch(e){ res.status(500).send() } })
方案2:改用findByIdAndDelete(更推荐)
router.delete('/users/me', auth, async(req, res)=>{ try{ const user = await User.findByIdAndDelete(req.user._id) if(!user){ return res.status(404).send() } res.send(user) }catch(e){ res.status(500).send() } })
验证测试
修改后重新运行测试,Should delete account for user测试中的expect(user).toBeNull()会正确验证用户已被删除。
原问题关键代码参考
Express删除路由(问题代码)
router.delete('/users/me',auth, async(req, res)=>{ try{ req.user.remove() // 缺少await res.send(req.user) }catch(e){ res.status(500).send() } })
测试代码中的删除测试
test('Should delete account for user', async () => { await request(app) .del('/users/me') .set('Authorization', `Bearer ${userOne.tokens[0].token}`) .send() .expect(200) const user = await User.findById(userOneId) expect(user).toBeNull() })
内容的提问来源于stack exchange,提问作者Upendra Bhanushali
相关产品推荐
相关产品推荐

