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

Jest中mockImplementation无法覆盖模块初始Mock函数的问题求助

Jest中mockImplementation无法覆盖模块初始Mock函数的问题求助

我最近在测试一个简单的Node API端点时,遇到了Jest mock的问题,想请大家帮忙看看。

先贴一下我的路由代码:

import { getRaces } from '@/services/races';
import { Request, Response, Router } from 'express';
import passport from 'passport';

export default (app: Router) => {
  app.get('/races', passport.authenticate('jwt', { session: false }), async (req: Request, res: Response) => {
    console.log(req);
    if (req.user) {
      res.status(200).json({ races: await getRaces() });
    } else {
      res.status(401).json({ error: 'Unauthorized' });
    }
  });
};

然后是测试代码:

import express from 'express';
import passport from 'passport';
import request from 'supertest';

import { getRaces } from '@/services/races';

import charactersRoute from './races';

jest.mock('@/services/races');
jest.mock('passport', () => ({
  authenticate: jest.fn(() => (req, _res, next) => {
    req.user = { id: 'test-user' }; // Mock authenticated user
    next();
  }),
}));

const app = express();
app.use(express.json());
const router = express.Router();
charactersRoute(router);
app.use(router);

describe('GET /races', () => {
  it('should return 200 and a list of races when authenticated', async () => {
    const mockRaces = [
      { id: 1, name: 'Elf' },
      { id: 2, name: 'Dwarf' },
    ];
    (getRaces as jest.Mock).mockResolvedValue(mockRaces);

    const response = await request(app).get('/races');

    expect(response.status).toBe(200);
    expect(response.body).toEqual({ races: mockRaces });
  });

  it('should return 401 when not authenticated', async () => {
    (passport.authenticate as jest.Mock).mockImplementation(() => (_req, _res, next) => {
      next();
    });

    const response = await request(app).get('/races');

    expect(response.status).toBe(401);
    expect(response.body).toEqual({ error: 'Unauthorized' });
  });
});

第一个测试是正常工作的:模拟的认证用户能通过校验,接口返回200状态码,并且模拟的数据也正确返回了。

但是第二个测试出问题了:我想用mockImplementation修改passport.authenticate的mock实现,让它不设置req.user,这样就能触发接口里的401分支。但实际运行时,这个新的mock根本没生效,还是调用了初始的那个mock,导致req.user依然存在,测试失败。我打印日志看了下,初始的mock被调用了两次。

我已经尝试过以下方法,但都没解决问题:

  • 调整passport的导入顺序,想解决作用域的问题,但我的Prettier和ESLint插件会自动把导回到文件顶部
  • 在beforeEach里尝试重置mock:(passport.authenticate as jest.Mock).resetMock()

有没有大佬能帮我分析下原因,或者给出解决办法?

备注:内容来源于stack exchange,提问作者mealeyst

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 14:15:28