Angular:测试返回可观察值的守卫

标签 angular unit-testing jasmine rxjs karma-runner

我正在尝试测试一个返回可观察值并调用另一个函数的身份验证防护。我的守卫看起来像这样(摘自托德座右铭。干杯托德):

@Injectable()
export class ProductSummaryLoadedGuard implements CanActivate {
  constructor(private store: Store<fromProductStore.State>) {}

  canActivate(): Observable<boolean> {
    return this.checkStore().pipe(
      switchMap(() => of(true)),
      catchError(() => of(false))
    );
  }

  checkStore(): Observable<boolean> {
    return this.store.pipe(select(fromProductStore.selectProductLoaded)).pipe(
      tap(loaded => {
        if (!loaded) {
          this.store.dispatch(new fromProductStore.LoadProductSummary());
        }
      }),
      filter(loaded => loaded),
      take(1)
    );
  }
}

我已经为此整理了规范的框架,导致问题的摘录如下:

it('should return true when checkStore() returns true', () => {
  spyOn(guard, 'checkStore').and.returnValue(of(true));

  const result = guard.canActivate();
  expect(result).toBeObservable(of(true));
});

执行此规范时,我在 Karma 中遇到此错误:

TypeError: Cannot read property 'indexOf' of undefined at Function.TestScheduler.parseMarbles (./node_modules/rxjs/_esm5/internal/testing/TestScheduler.js?:243:21)

我在这里缺少什么?我不想仅针对这一种方法使用弹珠测试,但如果有人可以建议一种方法,那么我很乐意尝试!

最佳答案

示例Effect testing来自 NgRx 的代码显示使用 toBeObservable 因此:

const expected = hot('-------a', {
  a: {
    type: '[Customers API] Search Customers Success',
    customers: [...],
  },
});

expect(
  effects.searchCustomers$({
    debounce: 20,
    scheduler: getTestScheduler(),
  })
).toBeObservable(expected);

.toBeObservable() 需要一个 TestHotObservableTestColdObservable,它们具有 marbles 属性。我来到这里是因为我收到错误 TypeError: Cannot read property 'marbles' of undefined by using .toBeObservable() with noparameters。

如果您想使用非 TestXXXObservable 类型的可观察量进行测试,则必须订阅它们并在订阅中验证结果为 NgRx testing example显示:

// create an actions stream and immediately dispatch a GET action
actions$ = of({ type: '[Customers Page] Get Customers' });

// mock the service to prevent an HTTP request
customersServiceSpy.getAllCustomers.and.returnValue(of([...]));

// subscribe to the Effect stream and verify it dispatches a SUCCESS action
effects.getAll$.subscribe(action => {
  expect(action).toEqual({
    type: '[Customers API] Get Customers Success',
    customers: [...],
  });
});

关于Angular:测试返回可观察值的守卫,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53211591/

相关文章:

angular - 如果该组件已经存在一个类,则 routerLinkActive 类不适用

Angular 自定义验证器错误(预期验证器返回 Promise 或 Observable)

unit-testing - Angular 2. 在单元测试中发出悬停事件

jquery - jquery.simulate.js 和 jQuery 事件方法之间的区别?

javascript - 引用错误 : Can't find variable: Map

angular - Jasmine : Spying an exported function that is called by an another function doesn't work

javascript - 'this' 在 Angular、XML2JS 中未定义

库中组件的 CSS 文件未随 Angular 应用程序中的组件一起加载

unit-testing - 使用 'traditional'记录/重播与Moq模型进行模拟

Angular2 2.0.0 组件单元测试导致错误 : Bootstrap at least one component before injecting Router