【问题标题】:How do I test an effect that returns multiple actions如何测试返回多个动作的效果
【发布时间】:2017-08-01 02:48:01
【问题描述】:

我有一个返回动作 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


    【解决方案1】:

    我发现了toArray 运算符:

    "收集所有源排放并将它们作为数组排放,当 源完成。”

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

    【讨论】:

      【解决方案2】:

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

      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();
        });
      

      【讨论】:

        【解决方案3】:

        像这样成对使用:

        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: {}});
              });
          }));
        

        【讨论】:

          【解决方案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)...

          【讨论】:

            猜你喜欢
            • 2018-06-16
            • 1970-01-01
            • 2022-01-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-02-26
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多