ts-node运行测试时Router.use()要求中间件函数却得到undefined如何解决
问题原因
根因是循环依赖(循环导入),从错误调用栈就能梳理出完整的循环链条:
- 测试文件
required-authorization.test.ts引入了鉴权中间件required-authorization.ts - 鉴权中间件里引入了同目录下的
../index(也就是web-server入口文件) - web-server入口文件加载路由配置文件
src/web-server/routes/index.ts - 路由配置文件又反过来导入了
requiredAuthorization鉴权中间件
Node.js的模块加载机制下,还未初始化完成的模块导出值会是undefined,因此router.use拿到的requiredAuthorization是undefined,就会抛出「需要传入中间件函数但得到undefined」的错误。普通运行服务时没报错是因为加载顺序和测试场景不同,没有触发这个循环加载路径。
解决方案
方案1:拆分公共实例,打破循环依赖(推荐,适合生产代码优化)
把你写在src/web-server/index.ts里的autho实例抽离到独立的公共文件,避免中间件引入web-server入口:
- 新建
src/utils/autho.ts,把原来web-server入口里初始化autho的代码全部迁移到这个文件:
// 示例,替换成你自己的autho初始化逻辑 import * as admin from 'firebase-admin' admin.initializeApp({/* 你的配置 */}) export const autho = admin
- 修改鉴权中间件的导入语句,替换原来的引入路径:
// 删掉原来的 import { autho } from '../index'; import { autho } from '../../utils/autho';
方案2:测试时Mock循环依赖(适合临时修复测试用例)
如果暂时不想修改生产代码,可以直接在测试文件顶部Mock掉循环依赖的模块,避免加载web-server入口:
// 写在所有import语句之前 jest.mock('../index', () => ({ autho: { auth: () => ({ verifyIdToken: jest.fn().mockResolvedValue({}) }) } }))
修改完成后重新运行测试,错误就会消失。
内容的提问来源于stack exchange,提问作者Felipito
相关产品推荐
相关产品推荐

