Angular5单元测试:spyOn监听的方法未被调用问题排查
parseSchema方法未被调用问题排查 我来帮你排查这个单元测试里spyOn监测的方法没被调用的问题,结合你的组件代码来看,主要有几个常见原因和对应的解决办法:
1. 未给dataplanDetails Input提供可触发回调的Observable
你的组件在ngOnInit里订阅了dataplanDetails这个@Input Observable,但如果测试中没有给它赋值一个能发出数据的Observable,订阅回调就不会执行,自然parseSchema不会被调用。
解决办法:
用RxJS的of()创建一个带有模拟数据的Observable,赋值给组件的dataplanDetails,确保它能发出触发回调的数据。
2. Spy创建的时机错误
如果在组件初始化(比如fixture.createComponent()之后、fixture.detectChanges()之后)才创建spyOn(component, 'parseSchema'),那组件初始化时的parseSchema调用已经发生了,spy根本捕获不到这次调用。
解决办法:
在触发组件生命周期钩子(比如ngOnInit)之前就创建spy,也就是在fixture.detectChanges()之前设置好spy。
3. 未触发Angular变化检测
Angular的组件生命周期钩子(比如ngOnInit)需要在变化检测触发时才会执行,如果测试中设置了Input但没有调用fixture.detectChanges(),ngOnInit可能不会自动执行。
解决办法:
在设置好dataplanDetails之后,调用fixture.detectChanges()来触发组件的初始化逻辑。
完整的修正测试代码示例
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { of } from 'rxjs'; import { JsonformComponent } from './jsonform.component'; fdescribe('JsonformComponent', () => { let component: JsonformComponent; let fixture: ComponentFixture<JsonformComponent>; // 模拟dataplanDetails发出的测试数据 const mockSubmissionSchema = JSON.stringify({ type: 'object', properties: {} }); const mockDataplanData = of({ details: { submissionFileSchema: mockSubmissionSchema } }); beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [ JsonformComponent ] }) .compileComponents(); })); beforeEach(() => { fixture = TestBed.createComponent(JsonformComponent); component = fixture.componentInstance; // 先创建spy,确保能捕获到后续的调用 spyOn(component, 'parseSchema').and.callThrough(); // 给Input赋值可发出数据的Observable component.dataplanDetails = mockDataplanData; // 触发变化检测,执行ngOnInit和订阅回调 fixture.detectChanges(); }); it('should call parseSchema when dataplanDetails emits data', () => { // 验证方法被调用 expect(component.parseSchema).toHaveBeenCalled(); // 验证调用参数是否正确 expect(component.parseSchema).toHaveBeenCalledWith(mockSubmissionSchema); }); });
另外还要注意:如果你的dataplanDetails是异步获取的(比如来自HTTP请求),可能需要用fakeAsync+tick或者async+whenStable来处理异步逻辑,但上面的示例用of()是同步Observable,detectChanges就足够触发回调了。
内容的提问来源于stack exchange,提问作者Shamoon

