Как правильно использовать Jasmine-Marbles для тестирования нескольких действий в ofType - PullRequest
0 голосов
/ 15 октября 2019

У меня есть Эффект, который вызывается каждый раз, когда он получает действие более чем одного "вида"

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

1 Ответ

1 голос
/ 23 октября 2019

В этом коде есть две проблемы.

  1. Предполагается, что getSomeDataViaHTTP возвращает два значения. Это неверно, ответ ничем не отличается от вашего первого примера: '-a |'
  2. Ожидается, что второе успешное действие появится через 40 мс (--b - b, считать количество тире). Это не правильно, потому что actionTwo происходит через 20 мс (-aa), а ответ занимает еще 10 мс (-a). Итак, первое успешное действие - после 20 мс (10 + 10), второе - после 30 мс (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);
});

Испытание мрамора - это круто, но оно включает в себя черную магию, которую вы должны подготовитьза. Я очень рекомендую вам внимательно прочитать эту превосходную статью , чтобы глубже понять предмет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...