【问题标题】:Test component using combineLatest使用 combineLatest 测试组件
【发布时间】:2019-07-26 19:41:37
【问题描述】:

尝试对具有 rxjs combineLatest 调用 Ngrx 选择器的组件进行单元测试。我似乎找不到模拟返回数据的方法。

我尝试过使用jasmine-marbles 和of() 似乎都没有刷新数据。

功能

private onSelectedCard(selectedCard: Card) {
    this.selectedCard = selectedCard;
    if (this.selectedCard !== undefined) {
      this.storeSelectLatest$ = combineLatest(
        this.store.pipe(select(fromBacklog.getListById(this.selectedCard.planId, this.selectedCard.listId))),
        this.store.pipe(select(fromBacklog.getPlanById(this.selectedCard.planId))),
        this.store.pipe(select(fromBacklog.getPlans)),
        (list, plan, plans) => ({ list, plan, plans }),
      );

      this.storeSelectLatest$.pipe(takeUntil(this.unsubscribe$)).subscribe(({ list, plan, plans }) => {
        this.listWithSelectedCard = list;
        this.activeListsOnPlanWithSelectedCard = [...plan.lists.filter(listInPlan => listInPlan.id !== 0 && listInPlan.active)];
        this.plansLoaded = plans;
        const cardIndex: number = list.cards.findIndex(card => card.id === this.selectedCard.id);
        const listIndex: number = this.activeListsOnPlanWithSelectedCard.findIndex(l => l.id === list.id);
        const planIndex: number = plans.findIndex(p => p.id === plan.id);

        this.canMoveUp = cardIndex > 0 || planIndex > 0 || listIndex > 0;

        this.canMoveDown =
          (cardIndex >= 0 && cardIndex < list.cards.length - 1) ||
          planIndex < plans.length - 1 ||
          listIndex < this.activeListsOnPlanWithSelectedCard.length - 1;
      });
    }
  }

测试

it('should highlight all the buttons for a selected card in the middle of the list', async(() => {
      component.storeSelectLatest$ = cold('-a', { a: { list: mockList, board: mockBoard, boards: [mockBoard] } });

      component['onSelectedCard'](mockCard);

      getTestScheduler().flush();
      fixture.detectChanges();
      expect(component.canMoveUp).toBeTruthy();
    }));

也试过了

it.only('should highlight all the buttons for a selected card in the middle of the list', async(() => {
      component.storeSelectLatest$ = of({ list: mockList, board: mockBoard, boards: [mockBoard] });

      component['onSelectedCard'](mockCard);

      expect(component.canMoveUp).toBeTruthy();
    }));

希望测试通过。 相反,我得到了

TypeError:您在预期流的位置提供了无效对象。 您可以提供 Observable、Promise、Array 或 Iterable。

【问题讨论】:

    标签: angular rxjs jestjs


    【解决方案1】:

    FWIW,ngrx 8 允许你模拟选择器:

    https://medium.com/ngrx/announcing-ngrx-version-8-ngrx-data-create-functions-runtime-checks-and-mock-selectors-a44fac112627

    如果您不想升级,我建议您通过模拟对store.pipe 的调用来解决此问题,并让它们返回您选择的可观察对象。也就是说,升级在代码方面相当简单变化并提供大量价值。

    【讨论】:

    • 是的,我可以模拟出store.pipe = jest.fn(() =&gt; mockList),但问题是这需要为 combineLatest 完成,这意味着不止一次调用 store
    • 为什么不做多个?
    • store.pipe = jest.fn().mockReturnValueOnce(of(false)).mockReturnValueOnce(of(true));
    猜你喜欢
    • 2021-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-25
    • 2015-11-05
    • 2021-10-02
    相关资源
    最近更新 更多