Angular单元测试:如何用spyOnProperty将Mock的userData设为null
解决Angular测试中动态设置Mock属性值的问题
针对你遇到的无法在测试中动态修改AuthServiceMock的userData属性的问题,提供以下几种可行方案:
方案1:将Mock的userData改为Getter属性
修改原AuthServiceMock,把userData改成Getter属性,这样就能通过spyOnProperty控制返回值:
import { User } from "../shared/interface/user"; const authState: User = { uid: 'fakeuser', email: 'test@test.com', emailVerified: true }; export const AuthServiceMock = { ForgotPassword: () => {}, SignUp: () => {}, // 改为Getter属性 get userData() { return authState; } };
对应的测试代码:
it('Text Not Rendered - No User Data', () => { // 获取注入的AuthService实例 const authService = TestBed.inject(AuthService); // 监视userData的Getter,返回null spyOnProperty(authService, 'userData', 'get').and.returnValue(null); // 触发变更检测,更新ngIf状态 fixture.detectChanges(); const compiled = fixture.nativeElement as HTMLElement; // 确认目标元素不存在 expect(compiled.querySelector('#confirmText')).toBeNull(); });
方案2:直接修改Mock的属性值(无需修改原Mock)
由于TestBed使用useValue传入的是Mock对象的引用,可直接修改其userData属性,再触发变更检测:
it('Text Not Rendered - No User Data', () => { // 获取注入的AuthService实例并断言类型 const authService = TestBed.inject(AuthService) as typeof AuthServiceMock; // 直接将userData设为null authService.userData = null; // 触发变更检测 fixture.detectChanges(); const compiled = fixture.nativeElement as HTMLElement; expect(compiled.querySelector('#confirmText')).toBeNull(); });
注意:若多个测试存在属性值干扰,需在beforeEach中重置userData:
beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [VerifyEmailAddressComponent], providers: [{ provide: AuthService, useValue: AuthServiceMock }] }).compileComponents(); fixture = TestBed.createComponent(VerifyEmailAddressComponent); component = fixture.componentInstance; // 重置userData为初始值 const authService = TestBed.inject(AuthService) as typeof AuthServiceMock; authService.userData = { uid: 'fakeuser', email: 'test@test.com', emailVerified: true }; fixture.detectChanges(); });
方案3:使用useFactory创建独立Mock实例
为避免测试间互相影响,用useFactory为每个测试生成独立的Mock对象:
beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [VerifyEmailAddressComponent], providers: [ { provide: AuthService, useFactory: () => ({ ForgotPassword: () => {}, SignUp: () => {}, userData: { uid: 'fakeuser', email: 'test@test.com', emailVerified: true } }) } ] }).compileComponents(); fixture = TestBed.createComponent(VerifyEmailAddressComponent); component = fixture.componentInstance; fixture.detectChanges(); });
每个测试都会得到全新的Mock实例,修改userData不会影响其他测试,测试代码同方案2。
内容的提问来源于stack exchange,提问作者Rusty Shackleford
相关产品推荐
相关产品推荐

