0

我有一个 NGRX 效果 - 根据状态 - 发出延迟的动作或什么都不发出。我想写一个测试,涵盖这两种情况。

这是效果:

myEffect$ = createEffect(() =>
  this.actions$.pipe(
    ofType(MyAction),
    filter(state => state.foo === false),
    delay(4000),
    map(state => myOtherAction())
  )
);

测试它应该发出带有延迟的 otherAction 的情况可以正常工作:

describe('emit my action', () => {
   const action = MyAction();

   it('should return a stream with myOtherAction', () => {
      const scheduler = getTestScheduler();
      scheduler.run(helpers => {
        // build the observable with the action
        actions = hot('-a', { a: action });

        // define what is the expected outcome of the effect
        const expected = {
           b: MyOtherAction()
        };
        helpers.expectObservable(effects.myEffect$).toBe('- 4000ms b', expected);
      });
   });
});

但我不知道如何测试另一个状态,它不应该发出另一个动作(流的长度为零):

   it('should return an empty stream', () => {
      store.setState({
        myFeature: {
           foo: true
        }
      });
      // ???
   });

请帮忙 :)

4

2 回答 2

0

由于 AliF50 的提示,我用filter“Noop Action”(= 没有任何侦听器的正常操作)替换了链中的(阻止 Observable 发射)。因此foo,我没有检查过滤器中的属性,而是noopAction在 foo 为真时返回地图中的 ,而当它为假时返回 otherAction 。

效果:

myEffect$ = createEffect(() =>
  this.actions$.pipe(
    ofType(MyAction),
    //filter(state => state.foo === false),
    delay(4000),
    map(state => state.foo !== false ? noopAction() : myOtherAction())
  )
);

考试:

describe('emit my action', () => {
  const action = MyAction();

  it('should return a stream with myOtherAction', () => {
    const scheduler = getTestScheduler();
    scheduler.run(helpers => {
      // build the observable with the action
      actions = hot('-a', { a: action });
      // define what is the expected outcome of the effect
      const expected = {
        b: MyOtherAction()
      };
      helpers.expectObservable(effects.myEffect$).toBe('- 4000ms b', expected);
    });
  });

  it('should return a stream with noop action as foo is true', () => {
    store.setState({
      myFeature: {
        foo: true
      }
    });
    const scheduler = getTestScheduler();
    scheduler.run(helpers => {
      // build the observable with the action
      actions = hot('-a', { a: action });
      // define what is the expected outcome of the effect
      const expected = {
        b: NoopAction()
      };
      helpers.expectObservable(effects.myEffect$).toBe('- 4000ms b', expected);
    });
  });

});
于 2021-01-12T12:12:02.183 回答
0

这将很难做到,因为过滤器会阻止效果返回可观察对象。

选项 1: // 无论你在哪里调度 MyAction,只有在创建的动作的 foo 属性为 true 时才调度它

选项2://更改效果的结构以返回空

import { EMPTY } from 'rxjs';
....
myEffect$ = createEffect(() =>
  this.actions$.pipe(
    ofType(MyAction),
    delay(4000),
    map(state => state.foo ? myOtherAction() : EMPTY)
  )
);

考试:

import { EMPTY } from 'rxjs';
....
describe('emit my action', () => {
   const action = MyAction();
   action.foo = false; // set foo property to false

   it('should return a stream with myOtherAction', () => {
      const scheduler = getTestScheduler();
      scheduler.run(helpers => {
        // build the observable with the action
        actions = hot('-a', { a: action });

        // define what is the expected outcome of the effect
        const expected = {
           b: EMPTY // assert now it is empty
        };
        helpers.expectObservable(effects.myEffect$).toBe('- 4000ms b', expected);
      });
   });
})
于 2021-01-11T21:10:30.773 回答