Angular信号测试报错及信号值修改方案咨询
解决Angular独立组件测试中Signal相关的两个问题
1. 修复TypeError: this.userMfaAuthRequired is not a function
这个错误的核心是Signal的mock方式与组件实际使用方式不匹配,常见两种场景:
场景A:组件中对Signal属性的调用方式错误
如果你的AuthState中userMfaAuthRequired是Signal属性(而非返回Signal的方法),在组件TS代码中必须通过调用它来取值:
// 组件内正确写法 canShowLogin = computed(() => !this.authState.userMfaAuthRequired());
此时mock时需要创建一个可调用的Signal对象,而非普通属性:
// 测试文件中正确mock方式 const userMfaSignal = signal(false); // 用真实的MutableSignal const stateMock = { userMfaAuthRequired: userMfaSignal } as AuthState;
场景B:误将Signal属性mock成方法
如果你错误地用createSpyObj把userMfaAuthRequired当成方法来mock:
// 错误的mock const stateMock = jasmine.createSpyObj('AuthState', ['userMfaAuthRequired']);
但实际AuthState中它是属性,组件调用this.authState.userMfaAuthRequired()就会报错。此时需要调整mock方式,改为模拟属性而非方法:
// 正确的mock(模拟属性) const stateMock = jasmine.createSpyObj('AuthState', [], { userMfaAuthRequired: signal(false) // 给属性赋值为Signal });
2. 动态修改mock Signal的值以测试多场景
要在测试中动态改变Signal的值,有两种可靠方案:
方案1:使用真实的MutableSignal
直接创建可变Signal,测试时调用set()或update()修改值:
// 初始化mock const userMfaAuthRequired = signal(false); const stateMock = { userMfaAuthRequired } as AuthState; // 测试场景1:MFA未要求,canShowLogin应为true expect(component.canShowLogin()).toBe(true); // 修改Signal值,测试场景2:MFA已要求,canShowLogin应为false userMfaAuthRequired.set(true); expect(component.canShowLogin()).toBe(false);
方案2:用Spy模拟可调用的Signal
如果需要跟踪调用次数,可以创建Spy函数作为Signal,动态修改返回值:
// 初始化mock Spy const userMfaSpy = jasmine.createSpy().and.returnValue(false); const stateMock = { userMfaAuthRequired: userMfaSpy as unknown as Signal<boolean> } as AuthState; // 测试场景1 expect(component.canShowLogin()).toBe(true); // 修改Spy返回值,测试场景2 userMfaSpy.and.returnValue(true); expect(component.canShowLogin()).toBe(false); // 可选:验证Signal是否被调用 expect(userMfaSpy).toHaveBeenCalled();
注意事项
- 计算信号
canShowLogin会自动跟踪依赖的Signal变化,修改userMfaAuthRequired的值后,无需手动触发变更检测(Angular测试环境会自动处理)。 - 确保mock的
AuthState类型正确,可通过as AuthState或Partial<AuthState> as AuthState规避类型报错。
内容的提问来源于stack exchange,提问作者Saeid Khodarahmi
相关产品推荐
相关产品推荐

