【问题标题】:How to properly use jasmine-marbles to test multiple actions in ofType如何正确使用 jasmine-marbles 测试 ofType 中的多个操作
【发布时间】:2019-10-23 19:50:08
【问题描述】:

我有一个 Effect,每次接收到多个“种类”的动作时都会调用它

myEffect.effect.ts

  someEffect$ = createEffect(() =>
    this.actions$.pipe(
      ofType(fromActions.actionOne, fromActions.actionTwo),
      exhaustMap(() => {
        return this.myService.getSomeDataViaHTTP().pipe(
          map((data) =>
            fromActions.successAction({ payload: data})
          ),
          catchError((err) =>
            ObservableOf(fromActions.failAction({ payload: err }))
          )
        );
      })
    )
  );

在我的测试中,我尝试“模拟两种不同的操作,但我总是以错误告终,而如果我尝试使用一个操作,它会完美运行

每个部分之前

describe('MyEffect', () => {
  let actions$: Observable<Action>;
  let effects: MyEffect;
  let userServiceSpy: jasmine.SpyObj<MyService>;
  const data = {
  // Some data structure
  };
  beforeEach(() => {
    const spy = jasmine.createSpyObj('MyService', [
      'getSomeDataViaHTTP',
    ]);
    TestBed.configureTestingModule({
      providers: [
        MyEffect,
        provideMockActions(() => actions$),
        {
          provide: MyService,
          useValue: spy,
        },
      ],
    });

    effects = TestBed.get(MyEffect);
    userServiceSpy = TestBed.get(MyService);
  });

这很好用

    it('should return successActionsuccessAction', () => {
    const action = actionOne();
    const outcome = successAction({ payload: data });

    actions$ = hot('-a', { a: action });
    const response = cold('-a|', { a: data });
    userServiceSpy.getSomeDataViaHTTP.and.returnValue(response);

    const expected = cold('--b', { b: outcome });
    expect(effects.someEffect$).toBeObservable(expected);
  });

这行不通

it('should return successAction', () => {
const actions = [actionOne(), actionTwo()];
const outcome = successAction({ payload: data });
actions$ = hot('-a-b', { a: actions[0], b: actions[1] });
const response = cold('-a-a', { a: data });
userServiceSpy.getSomeDataViaHTTP.and.returnValue(response);
const expected = cold('--b--b', { b: outcome });
expect(effects.someEffect$).toBeObservable(expected);
});

【问题讨论】:

    标签: ngrx-effects jasmine-marbles


    【解决方案1】:

    这段代码有两个问题。

    1. 这表明 getSomeDataViaHTTP 返回两个值。这是错误的,响应与您的第一个示例没有什么不同:'-a|'
    2. 它预计第二个successAction 将在40 毫秒后出现(--b--b,计算破折号的数量)。这是不正确的,因为 actionTwo 发生在 20 毫秒 (-a-a) 之后,响应又需要 10 毫秒 (-a)。所以第一个successAction是在20ms之后(10+10),第二个是在30ms之后(20+10)。弹珠是:'--b-b'。
    Input actions     : -a -a
    1st http response :  -a
    2nd http response :     -a
    Output actions    : --b -b
    

    工作代码:

    it('should return successAction', () => {
      const actions = [actionOne(), actionTwo()];
      actions$ = hot('-a-b', { a: actions[0], b: actions[1] });
    
      const response = cold('-a|', { a: data });
      userServiceSpy.getSomeDataViaHTTP.and.returnValue(response);
    
      const outcome = successAction({ payload: data });
      const expected = cold('--b-b', { b: outcome });
      expect(effects.someEffect$).toBeObservable(expected);
    });
    

    大理石测试很酷,但它涉及一些你应该准备的黑魔法。我非常建议您仔细阅读this excellent article 以更深入地了解该主题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-13
      • 2018-05-15
      • 2018-01-04
      • 2019-10-13
      • 1970-01-01
      • 1970-01-01
      • 2019-02-06
      相关资源
      最近更新 更多