Jasmine测试报错Cannot read properties of undefined (reading 'subscribe')求解
错误原因
核心触发点是 this.managePackageService.getPackages() 调用后返回了 undefined,调用 subscribe 方法时自然抛出空属性读取错误,常见触发场景有两个:
- 你的
AddProductComponent在初始化生命周期(如ngOnInit)中直接调用了subscriptionPackages()方法,而你给getPackagesspy设置返回值的时机太晚:你在it测试用例块中才设置返回值,但beforeEach里执行fixture.detectChanges()时就已经触发了组件初始化逻辑,此时spy还没配置返回值,默认返回undefined。 - 未正确导入RxJS的
of操作符,导致你设置的返回值本身是undefined。
解决方案
1. 提前配置spy的默认返回值
把getPackages的返回值配置移到组件实例创建之前,比如在第一个beforeEach中配置,同时确认已经导入of操作符:
// 顶部先导入of操作符 import { of } from 'rxjs'; // 其他代码保持不变 beforeEach(async () => { // 提前给spy设置默认返回值 packageServiceStub.getPackages.and.returnValue(of([])); await TestBed.configureTestingModule({ // 原有配置不变 }).compileComponents(); });
2. 按需调整变更检测时机
如果你的业务逻辑不需要组件初始化就触发subscriptionPackages(),也可以调整初始化阶段的变更检测逻辑,等你配置完spy再手动触发:
beforeEach(() => { fixture = TestBed.createComponent(AddProductComponent); component = fixture.componentInstance; component.packagePlan = [{'name':'basic', 'id':1}, {'name':'advance', 'id':2}, {'name':'premium', 'id':3}]; // 注释掉自动触发变更检测,在it块中需要时再手动调用 // fixture.detectChanges(); });
3. 修正测试用例逻辑
原测试用例的断言逻辑不合理,应该验证subscriptionPackages()调用后packagePlan被正确赋值为接口返回的mock数据,而不是仅判断是否为真值:
it('should get package list when subscriptionPackages is called', () => { const mockpackageResponse = [{name:'test', id:4}]; packageServiceStub.getPackages.and.returnValue(of(mockpackageResponse)); component.subscriptionPackages(); // 验证值被正确覆盖 expect(component.packagePlan).toEqual(mockpackageResponse); // 验证spy被正确调用 expect(packageServiceStub.getPackages).toHaveBeenCalled(); });
内容的提问来源于stack exchange,提问作者aparna bhargav
相关产品推荐
相关产品推荐

