You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jest测试用户密码更新接口遇5000ms超时问题求助

解决Jest测试密码更新接口超时问题

我是Jest新手,现有一个用户密码更新接口功能正常,但使用Jest测试时出现“Exceeded timeout of 5000 ms for a test”超时错误,怀疑测试代码存在问题。

后端密码更新代码

const AppError = require('../utils/appError');
const catchAsync = require('../utils/catchAsync');
const User = require('../models/userModel');


exports.updatePassword = catchAsync(async (req, res, next) => {
  // Get user from collection
  const user = await User.findById(req.user.id).select('+password');
  console.log(user);
  // Check if POSTed current password is correct
  if (!(await user.correctPassword(req.body.passwordCurrent, user.password))) {
    return next(new AppError('Your current password is wrong', 401));
  }

  // If so, update the password
  user.password = req.body.password;
  user.passwordConfirm = req.body.passwordConfirm;
  await user.save();
  // Log user in, send JWT
  // res.send('sent');
  createSendToken(user, 200, res);
});

Jest测试代码

const request = require('supertest');
const app = require('../app');
const mongoose = require('mongoose');
const jwt = require('jsonwebtoken');
const User = require('../models/userModel');

const userOneId = new mongoose.Types.ObjectId();

const userOne = {
  _id: userOneId,
  name: 'blackcypher',
  email: 'blackcypher@gmail.com',
  password: 'comeonboys',
  passwordConfirm: 'comeonboys',
};

beforeEach(async () => {
  await mongoose.connect('mongodb://localhost:27017/tour-test');
  await User.deleteMany();

  await new User(userOne).save();
});

afterEach(async () => {
  await mongoose.connection.close();
});


test('Should update a user profile', async () => {

  const response = await request(app)
    .patch('/api/v1/users/updateMyPassword')
    .set(
      'Authorization',
      `Bearer ${jwt.sign({ userOneId }, process.env.JWT_SECRET, {
        expiresIn: process.env.JWT_EXPIRES_IN,
      })}`
    )
    .send({ passwordCurrent: 1234, password: 12345, passwordConfirm: 12345 })
    .expect(200);
});

问题排查与修复方案

  • JWT Payload键名错误
    生成JWT时传入的payload是{ userOneId },但后端通过req.user.id获取用户ID,键名不匹配会导致req.user.id为undefined,User.findById无法找到用户,异步操作卡住超时。修正JWT生成代码:

    `Bearer ${jwt.sign({ id: userOneId }, process.env.JWT_SECRET, {
      expiresIn: process.env.JWT_EXPIRES_IN,
    })}`
    
  • 密码验证不匹配导致响应预期不符
    测试中传入的passwordCurrent: 1234与用户实际密码comeonboys不匹配,后端会返回401错误,但测试预期200,supertest会一直等待符合预期的响应直到超时。要么将passwordCurrent改为comeonboys,要么将测试预期状态码改为401(如果是验证错误密码的场景)。

  • 数据库连接重复操作耗时
    beforeEach中每次测试都重新连接数据库,增加了额外耗时。将连接移到beforeAll,断开移到afterAll:

    beforeAll(async () => {
      await mongoose.connect('mongodb://localhost:27017/tour-test');
    });
    
    beforeEach(async () => {
      await User.deleteMany();
      await new User(userOne).save();
    });
    
    afterAll(async () => {
      await mongoose.connection.close();
    });
    
  • 检查createSendToken函数
    后端调用了createSendToken但未提供该函数代码,如果该函数存在未处理的异步操作或未正确发送响应,会导致请求挂起超时。确保该函数能正常完成并向客户端返回响应。

内容的提问来源于stack exchange,提问作者Tosin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 15:53:15