如何测试返回多个操作的效果

问题描述 投票:0回答:5

我有一个效果,先返回动作 A,然后返回动作 B

@Effect() myEffect$: Observable <Action> = this.actions$
  .ofType('MY_ACTION')
  .switchMap(() => Observable.of(
    // subscribers will be notified
    { type: 'ACTION_ONE' },
    // subscribers will be notified (again ...)
    { type: 'ACTION_TWO' }
  ));

如何测试连续返回的两个动作?

it('should return action one then action two', () => {
  runner.queue(new myAction());
  const expectedResult = twoSuccesiveActions;
  sessionEffect.myEffect$.subscribe(result => {
    // how do I test those two succesively returned actions
    expect(result).toEqual(expectedResult);
  });
});
angular redux rxjs ngrx ngrx-effects
5个回答
4
投票

您可以使用一个带有

take(1)
和一个带有
skip(1)
:

it('should return action one then action two', () => {
  const expectedResult = twoSuccesiveActions;
  sessionEffect.myEffect$.take(1).subscribe(result => {
    // first action
    expect(result).toEqual(expectedResult);
  });

  sessionEffect.myEffect$.skip(1).take(1).subscribe(result => {
    // second action
    expect(result).toEqual(expectedResult);
  });

  runner.queue(new myAction());
});

无论如何,如果您不手动取消订阅,我建议您使用

take(1)
以确保不会泄漏到其他测试等...


3
投票

如果有人仍然想知道如何做,这是另一种方法

effects.myEffect$
  .pipe(
    bufferCount(2)
  )
  .subscribe((emittedActions) => {
    /* You could also include here callings to services
        verify(myServiceMock.execute(anything()))
          .called();
    */
    expect(emittedActions.map((action) => action.type))
      .toEqual([
        myFirstAction,
        mySecondAction,
      ]);
    done();
  });

1
投票

像这样成对使用:

it('should return a ACTION_ONE && ACTION_TWO',
  inject([EffectService, EffectsRunner], (service: EffectService, runner: EffectsRunner) => {
    runner.queue({type: USER_SWITCH_ROLE});

    service.myEffect$
      .pairwise()
      .subscribe(([result1, result2]) => {
        expect(result1).toEqual({type: ACTION_ONE, payload: {}});
        expect(result2).toEqual({type: ACTION_TWO, payload: {}});
      });
  }));

1
投票

我发现了

toArray
运算符:

“收集所有源排放,并在以下情况下将它们作为数组发出: 源码完成。”

sessionEffect.myEffect$
  .pipe(toArray())
  .subscribe(result =>
    expect(result).toHaveLength(2);
    expect(result[0]).toBeInstanceOf(ExpectedAction1);
    expect(result[1]).toBeInstanceOf(ExpectedAction2);
  });

0
投票

这对我来说更容易:

 service.myEffect$.pipe(
                reduce((acc, val) => {
                    acc.push(val);
                    return acc;
                }, [])
            )
            .subscribe((result) => {
                expect(result).toEqual([expectedAction1, expectedAction2]);
                done();
            });
© www.soinside.com 2019 - 2024. All rights reserved.