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
相关产品推荐
相关产品推荐

