Ionic单元测试使用ion-slides时抛出TypeError错误如何解决
问题定位
你遇到的TypeError: Cannot read properties of undefined (reading 'apply')错误,本质是调用this.slides.lockSwipeToNext(true)时触发的异常。触发原因如下:
- IonSlides底层依赖Swiper实例实现所有滑动相关方法,单元测试环境不会自动完成Swiper实例的初始化
- 代码中仅判断了
this.slides本身存在,但没有校验其内部依赖的Swiper实例是否初始化完成,调用方法时内部的apply操作找不到执行上下文就会抛出该错误
解决方案
可根据你的测试需求选择以下任意方案:
方案1:Mock IonSlides组件(最推荐单元测试使用)
单元测试优先隔离外部依赖,直接Mock IonSlides的所有用到的方法即可,不需要依赖真实组件实现:
// 首先导入自定义元素解析schema import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; describe('ReEvaluationComponent', () => { beforeEach(async(() => { NavParamsMock.setParams({ client: {dob: "1991-01-22"} }) TestBed.configureTestingModule({ declarations: [ ReEvaluationComponent ], imports: [ IonicModule.forRoot(), HttpClientTestingModule, RouterTestingModule, FormsModule, SharedModule, ReactiveFormsModule ], providers: [ {provide: Storage, useValue: storageMock}, {provide: NavParams, useValue: navParams}, {provide: WeighInsProvider, useValue: weighInsServiceMock}, {provide: GlobalsService, useValue: mockGlobalsService}, {provide: TransactionsProvider, useValue: transactionsServiceMock}, ], // 新增配置:忽略ion-*自定义元素的解析校验 schemas: [CUSTOM_ELEMENTS_SCHEMA] }).compileComponents(); })); // 其余前置逻辑不变 beforeEach(() => { fixture = TestBed.createComponent(ReEvaluationComponent); component = fixture.componentInstance; // 新增:Mock IonSlides的所有用到的方法 component.slides = { lockSwipeToNext: jasmine.createSpy('lockSwipeToNext'), // 其他用到的slides方法都可以在这里补充mock } as unknown as IonSlides; fixture.detectChanges(); }) it('should create', () => { expect(component).toBeTruthy(); }); })
方案2:等待Swiper实例初始化完成再操作
如果需要使用真实的IonSlides实现,修改组件代码先校验Swiper实例是否存在:
// 修改组件的ngAfterViewInit逻辑 async ngAfterViewInit() { if (this.slides) { const swiper = await this.slides.getSwiper(); if (swiper) { this.slides.lockSwipeToNext(true) } } }
同时修改测试用例的前置逻辑,等待异步初始化完成:
beforeEach(async () => { fixture = TestBed.createComponent(ReEvaluationComponent); component = fixture.componentInstance; fixture.detectChanges(); // 等待所有异步任务执行完成 await fixture.whenStable(); })
方案3:替换废弃组件
Ionic 6及以上版本已经正式废弃ion-slides,官方推荐直接使用Swiper.js官方提供的Angular组件,长期维护的项目可以考虑替换,避免后续API变动带来的兼容问题。
内容的提问来源于stack exchange,提问作者Jeremy Thomas
相关产品推荐
相关产品推荐

