如何用Jest测试subscribe后是否调用方法?解决subscribe未定义错误
问题修复方案
1. 修复服务类名拼写错误
测试代码中多处将RatingService误写为RaitingService(缺失字母t),这会导致Angular依赖注入无法正确匹配服务,组件内的this.ratingService无法正常注入。
将测试代码中所有RaitingService替换为RatingService:
let ratingService: RatingService; const ratingServiceMock ={ getRating: jest.fn() } // ... providers: [ { provide: RatingService, useValue: ratingServiceMock } ],
2. 导入RxJS的of操作符
测试中使用of(1)创建Observable,但如果未导入of,会导致of为undefined,getRating返回undefined,调用subscribe时就会抛出Cannot read properties of undefined (reading 'subscribe')错误。
在测试文件顶部添加导入语句:
import { of } from 'rxjs';
3. 优化测试用例逻辑(可选)
调整代码顺序,将mock返回值的设置放在调用目标方法之前,逻辑更清晰;同时可以增加参数断言,让测试更精确:
it('should trigger onHandling after getRating subscription', () => { const spy = jest.spyOn(component, 'onHandling'); // 先设置mock返回的Observable ratingServiceMock.getRating.mockReturnValue(of(1)); // 给currentRatingId设置有效值(根据组件实际类型调整) component.currentRatingId = 1; // 调用目标方法 component.getRatingId(); // 断言onHandling被调用且参数正确 expect(spy).toHaveBeenCalledTimes(1); expect(spy).toHaveBeenCalledWith(1); });
完整修复后的测试代码示例:
import { of } from 'rxjs'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { RatingComponent } from './rating.component'; import { RatingService } from './rating.service'; // 其他必要导入... describe('RatingComponent', () => { let component: RatingComponent; let fixture: ComponentFixture<RatingComponent>; let ratingService: RatingService; const ratingServiceMock ={ getRating: jest.fn() } beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [RatingComponent], schemas: [CUSTOM_ELEMENTS_SCHEMA], providers: [ { provide: RatingService, useValue: ratingServiceMock } ], imports: [ ReactiveFormsModule, RouterTestingModule, HttpClientTestingModule, MatDialogModule, BrowserAnimationsModule ], }).compileComponents(); }); beforeEach(() => { fixture = TestBed.createComponent(RatingComponent); component = fixture.componentInstance; fixture.detectChanges(); }); it('should trigger onHandling after getRating subscription', () => { const spy = jest.spyOn(component, 'onHandling'); ratingServiceMock.getRating.mockReturnValue(of(1)); component.currentRatingId = 1; component.getRatingId(); expect(spy).toHaveBeenCalledTimes(1); expect(spy).toHaveBeenCalledWith(1); }); });
内容的提问来源于stack exchange,提问作者unitestangular
相关产品推荐
相关产品推荐

