You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 14:54:02