如何在Jest中针对不同团队条件性模拟私有模块导入?
针对不同团队条件性模拟私有模块的Jest解决方案
1. 用环境变量切换模拟策略
通过设置TEAM_NAME环境变量,在Jest配置和测试文件中动态调整模拟规则,既规避私有依赖的访问问题,又能针对性测试不同团队的ChildComponent版本。
步骤示例:
- 运行测试时指定团队:
TEAM_NAME=team-awesome npm test - 在
jest.config.js中配置动态模块映射:
module.exports = { moduleNameMapper: (() => { const team = process.env.TEAM_NAME; const mocks = {}; // 按团队匹配私有依赖模拟 if (team === 'team-awesome') { mocks['@proprietary-X/things'] = '<rootDir>/__mocks__/proprietary-x-things.js'; } else if (team === 'team-amazing') { mocks['@proprietary-Y/stuff'] = '<rootDir>/__mocks__/proprietary-y-stuff.js'; } // 映射不同团队的ChildComponent到模拟或真实文件(若可访问) mocks['variations-team-awesome/foo-bar'] = team === 'team-awesome' && process.env.USE_REAL_COMPONENT ? '<rootDir>/node_modules/variations-team-awesome/foo-bar' : '<rootDir>/__mocks__/child-component-awesome.js'; mocks['variations-team-amazing/foo-bar'] = team === 'team-amazing' && process.env.USE_REAL_COMPONENT ? '<rootDir>/node_modules/variations-team-amazing/foo-bar' : '<rootDir>/__mocks__/child-component-amazing.js'; return mocks; })(), };
- 在测试文件中根据环境变量重置模块并执行测试:
describe('SharedComponent', () => { beforeEach(() => { jest.resetModules(); }); it('renders correctly for team-awesome', () => { process.env.TEAM_NAME = 'team-awesome'; const SharedComponent = require('./SharedComponent').default; // 编写测试断言逻辑 }); it('renders correctly for team-amazing', () => { process.env.TEAM_NAME = 'team-amazing'; const SharedComponent = require('./SharedComponent').default; // 编写测试断言逻辑 }); });
2. 自定义动态模拟模块
创建一个可根据团队切换的通用模拟模块,统一处理不同ChildComponent的依赖模拟:
- 在
__mocks__/child-component.js中编写动态模拟逻辑:
const team = process.env.TEAM_NAME; let ChildComponent; if (team === 'team-awesome') { const mockThings = require('./proprietary-x-things'); // 模拟team-awesome版本ChildComponent的核心逻辑,绑定模拟依赖 ChildComponent = function() { return { render: jest.fn().mockReturnValue('<div>Team Awesome Child</div>'), fetchData: jest.fn().mockImplementation(() => mockThings.fetchData()), }; }; } else if (team === 'team-amazing') { const mockStuff = require('./proprietary-y-stuff'); ChildComponent = function() { return { render: jest.fn().mockReturnValue('<div>Team Amazing Child</div>'), submitForm: jest.fn().mockImplementation(() => mockStuff.submitForm()), }; }; } else { throw new Error('请设置TEAM_NAME环境变量(team-awesome/team-amazing)'); } module.exports = ChildComponent;
- 在测试文件中直接映射不同团队的
ChildComponent导入到这个动态模拟:
jest.mock('variations-team-awesome/foo-bar', () => require('../__mocks__/child-component')); jest.mock('variations-team-amazing/foo-bar', () => require('../__mocks__/child-component')); describe('SharedComponent', () => { it('works with team-awesome', () => { process.env.TEAM_NAME = 'team-awesome'; const SharedComponent = require('./SharedComponent').default; // 执行测试断言 }); it('works with team-amazing', () => { process.env.TEAM_NAME = 'team-amazing'; const SharedComponent = require('./SharedComponent').default; // 执行测试断言 }); });
3. 结合Babel动态替换导入(构建阶段适配)
如果团队的ChildComponent替换是在构建时完成的,可借助babel-plugin-module-resolver统一管理导入路径,测试时替换为模拟模块:
- 在
babel.config.js中配置团队别名:
module.exports = { plugins: [ [ 'module-resolver', { alias: { 'child-component': process.env.TEAM_NAME === 'team-awesome' ? 'variations-team-awesome/foo-bar' : 'variations-team-amazing/foo-bar', }, }, ], ], };
- 在
jest.config.js中把别名指向模拟模块:
module.exports = { moduleNameMapper: { 'child-component': '<rootDir>/__mocks__/child-component.js', '@proprietary-X/things': '<rootDir>/__mocks__/proprietary-x-things.js', '@proprietary-Y/stuff': '<rootDir>/__mocks__/proprietary-y-stuff.js', }, };
内容的提问来源于stack exchange,提问作者AncientSwordRage
相关产品推荐
相关产品推荐

