【问题标题】:Angular unit test failing with error .catch is not a function角度单元测试失败并出现错误 .catch 不是函数
【发布时间】:2018-04-04 20:52:50
【问题描述】:

我有以下 sn-p 代码,它是在浏览器中运行良好的组件的一部分。但是当我运行我的 Karma/Jasmine 单元测试时,它失败了。

代码:

const request = this.queryQueue.pipe(switchMap(() => this.loadAppointments().catch(e => {
  return new Array<Appointment>();
})));

request.subscribe(
  newAppointments=> {
    this.appointments = this.myData.concat(newAppointments);
  }
);

注意事项:

  • queryQueue - 是一个主题
  • loadAppointments() - 执行 Web 服务请求并返回 Observable

加载约会

loadAppointments(): Observable<Appointment[]> {
  this.isLoading = true;
  return this.webApiService.getAppointments(this.getSearchDto(), this.appointments.length, 20);
}

目标:

  • 可观察管道由 queryQueue 对象启动
  • 从服务器请求数据并附加到当前数据列表中
  • 阻止长时间运行的请求在后续请求之后返回(因此是 switchMap)
  • 在 catch 中处理错误

错误:

TypeError: _this.loadAppointments(...).catch is not a function
    at SwitchMapSubscriber.eval [as project] (webpack:///./src/app/components/appointments/appointments.component.ts?:72:117)
    at SwitchMapSubscriber._next (webpack:///./node_modules/rxjs/_esm5/operators/switchMap.js?:94:27)
    at SwitchMapSubscriber.Subscriber.next (webpack:///./node_modules/rxjs/_esm5/Subscriber.js?:97:18)
    at Subject.next (webpack:///./node_modules/rxjs/_esm5/Subject.js?:66:25)
    at AppointmentsComponent.refresh (webpack:///./src/app/components/appointments/appointments.component.ts?:84:25)
    at AppointmentsComponent.set [as day] (webpack:///./src/app/components/appointments/appointments.component.ts?:42:18)
    at AppointmentsComponent.gotoToday (webpack:///./src/app/components/appointments/appointments.component.ts?:111:18)
    at AppointmentsComponent.ngOnInit (webpack:///./src/app/components/appointments/appointments.component.ts?:64:14)
    at checkAndUpdateDirectiveInline (webpack:///./node_modules/@angular/core/esm5/core.js?:12585:19)
    at checkAndUpdateNodeInline (webpack:///./node_modules/@angular/core/esm5/core.js?:14109:20)

单元测试:

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        AppointmentsComponent
      ],
      imports: [
        InfiniteScrollModule,
        FormsModule,
        BrowserAnimationsModule
      ],
      providers: [
        { provide: WebApiService, useClass: MockWebApiService }
      ]
    }).compileComponents();

  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(AppointmentsComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

/* ...Code missing for brevity... */

class MockWebApiService {
  getAppointments(): Observable<Appointment[]> { return of([]);}
}

【问题讨论】:

    标签: angular rxjs karma-jasmine


    【解决方案1】:

    鉴于测试在第一个测试用例上引发,您的代码示例必须在constructorngOnInit 中。如果它在构造函数中,请将其移至ngOnInit,因为它会使测试更加容易。

    它正在抛出,因为 switchMap 期望 this.loadAppointments() 返回一个 observable,但它没有。您需要模拟此方法以测试您的组件。

    beforeEach(() => {
      fixture = TestBed.createComponent(AppointmentsComponent);
      component = fixture.componentInstance;
    
      component.loadAppointments = () => of([]);
    
      fixture.detectChanges();
    });
    

    这个简单的更改应该可以防止测试过早失败。您也可以考虑使用jasmine.spy 监视loadAppointment 方法,但这实际上取决于您要测试的内容。

    【讨论】:

    • 不幸的是,这并没有完全做到。 loadAppointments() 调用另一个返回 Observable 的服务。我正在嘲笑该方法(我现在已将其包含在问题的编辑中)。正如您所建议的,我也尝试直接模拟 loadAppointments 方法,但这仍然导致相同的错误。
    猜你喜欢
    • 2023-01-22
    • 2018-11-18
    • 1970-01-01
    • 2021-05-08
    • 1970-01-01
    • 2017-11-19
    • 2011-08-24
    • 2019-07-20
    相关资源
    最近更新 更多