TypeScript单元测试中构造函数初始化及decrypt调用报错排查
解决VoiceService初始化时decrypt函数触发的TypeError问题
核心问题
测试环境中,decrypt函数接收的参数是undefined——要么是依赖的环境变量没设置,要么是decrypt本身没被正确mock,导致VoiceService构造函数执行时抛出TypeError[ERR_INVALID_ARG_TYPE]。
具体解决方案
补全测试环境变量
在测试初始化阶段(比如beforeEach)手动设置需要的加密环境变量,确保decrypt有合法参数:beforeEach(() => { // 模拟加密的授权令牌环境变量 process.env.VOICE_ENCRYPTED_TOKEN = 'test-encrypted-string'; });如果项目用
dotenv,可以加载测试专用的.env.test文件,统一管理测试环境变量。提前Stub decrypt函数
因为decrypt是在VoiceService构造函数里调用的,必须在实例化VoiceService之前完成stub,用sinon直接拦截这个函数的调用:import sinon from 'sinon'; import { decrypt } from '../utils/crypto'; // 替换成你的decrypt模块路径 beforeEach(() => { // 让decrypt返回测试用的授权头值 sinon.stub(decrypt).returns('Bearer test-token'); // 再初始化依赖和实例 const apiServiceStub = sinon.createStubInstance(ApiService); const voiceService = new VoiceService(apiServiceStub); const voiceController = new VoiceController(voiceService); });注意如果
decrypt是默认导出,要调整stub方式:sinon.stub(require('../utils/crypto'), 'default').returns(...)重构构造逻辑降低测试耦合(可选)
把生成授权头的逻辑抽成独立方法,方便测试时替换:class VoiceService { private authHeader: string; constructor(private apiService: ApiService) { this.authHeader = this.getAuthHeader(); } // 抽成独立方法,测试时可mock protected getAuthHeader(): string { return decrypt(process.env.VOICE_ENCRYPTED_TOKEN); } }测试时可以用子类mock或者直接stub这个方法:
// 方式1:用子类覆盖方法 class MockVoiceService extends VoiceService { protected getAuthHeader() { return 'Bearer test-token'; } } const voiceService = new MockVoiceService(apiServiceStub); // 方式2:用sinon stub protected方法 const voiceService = new VoiceService(apiServiceStub); sinon.stub(voiceService, 'getAuthHeader').returns('Bearer test-token');排查参数来源
打印环境变量确认是否存在,避免因为变量名拼写错误导致undefined:console.log('测试环境变量:', process.env.VOICE_ENCRYPTED_TOKEN);
内容的提问来源于stack exchange,提问作者Sweta Sharma
相关产品推荐
相关产品推荐

