Как я могу протестировать эффекты ngrx, используя жасминовые шарики?

Я не могу проверить эффекты NgRx. Вы можете мне помочь?

Друзья, помогите пожалуйста. Я хочу испытать какой-то эффект, но не могу. Я получаю сообщение об ошибке «Ожидается, что $ [0] .notification.value.payload будет разновидностью объекта, но был пользователем ({name: '1212', roles: ['somerole']})». Я не понимаю в чем дело.

эффект:

@Injectable({
  providedIn: 'root'
})
@Injectable()
export class AuthEffects {

  constructor(
    private actions$: Actions,
    private rootService: RootService,
    private router: Router,
  ) {
  }

  @Effect()
  authUser$: Observable<any> = this.actions$.pipe(
    ofType(authActions.FETCHING),
    map((action: authActions.Fetching) => action.payload),
    switchMap((paylod: UserRequest) => this.rootService.login(paylod)
        .pipe(
          map((value) => {
            const {sub, authorities} = value;
            this.router.navigate(['/customers-list']);
            return new authActions.Success(new User(sub, authorities));
          }),
          catchError(() => of(new authActions.Fail('wrong username or password')))
        )
    )
  );
}

спецификация:

describe('AuthEffects', () => {
  let effects: AuthEffects;
  let rootService: jasmine.SpyObj<RootService>;
  let actions: Observable<any>;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule, RouterTestingModule],
      providers: [
        RootService,
        AuthEffects,
        provideMockActions(() => actions),
        {
          provide: RootService,
          useValue: {
            login: jasmine.createSpy()
          }
        }
      ]
    });

    effects = TestBed.get(AuthEffects);
    rootService = TestBed.get(RootService);
  });

  it('should work', () => {
    const userRequest: UserRequest = {
      name: '1212',
      password: 'alsj'
    };
    const userResponse: UserResponse = {
      sub: '1212',
      authorities: ['somerole']
    };
    const editedUser: User = {
      name: '1212',
      roles: ['somerole']
    };
    const action = new authActions.Fetching(userRequest);
    const completion = new authActions.Success(editedUser);

    actions = hot('-a', {a: action});
    const response = cold('-a|', {a: userResponse});
    rootService.login.and.returnValue(response);
    const expected = cold('--b', {b: completion});

    expect(effects.authUser$).toBeObservable(expected);
  });
});

Я пробовал сделать это по какому-то примеру, но ничего не вышло.


person Heckler    schedule 25.04.2019    source источник


Ответы (2)


Вы должны внести незначительные изменения в то, как вы устанавливаете ожидаемый блок в тесте. Попробуйте следующее:

effects.authUser$.subscribe(actionSent => {
 expect(actionSent).toBeObservable(expected)
})

вместо того

expect(effects.authUser$).toBeObservable(expected);

Я надеюсь, что это сработает для вас.

person RV.    schedule 25.04.2019
comment
Хорошая попытка, но у меня возникла ошибка: Uncaught TypeError: actual.subscribe не является брошенной функцией - person Heckler; 26.04.2019
comment
Я получаю ту же ошибку, но не могу найти / не понимаю проблему. Вы знаете, в чем на самом деле проблема в этом случае? - person user3287019; 02.03.2020
comment
Это не будет работать, поскольку подписанный Observable больше не является Observable. Вы можете подписаться и проверить это с помощью toBe, да, но не с помощью toBeObservable. И тогда вы также не можете проверить возвращенное действие. Мраморное тестирование на самом деле существует, чтобы не нуждаться в подписке. У меня та же проблема, что теряется набор текста. Мне бы очень хотелось иметь что-то вроде предположения типа для шариков :(. - person seawave_23; 24.08.2020

похоже, что конструктор сломает это. Если я изменю код эффекта без конструктора - он работает

  @Effect()
  authUser$: Observable<any> = this.actions$.pipe(
    ofType(authActions.FETCHING),
    map((action: authActions.Fetching) => action.payload),
    switchMap((paylod: UserRequest): any => this.rootService.login(paylod)
        .pipe(
          map((value: UserResponse) => {
            const {sub, authorities} = value;
            return new authActions.Success({
              name: sub,
              roles: authorities
            });
          }),
          catchError(() => of(new authActions.Fail('wrong username or password')))
        )
    )
  );
person Heckler    schedule 26.04.2019
comment
Можно ответить на ваш собственный вопрос, но я отредактировал последний фрагмент, в котором вы спрашиваете, где вы ошиблись. Вы не должны задавать вопросы в ответах, так как все быстро становится беспорядочным, и становится трудно понять, какой ответ соответствует другому. Если вы все еще хотите узнать, что пошло не так, вы должны задать еще один вопрос (ссылка на него для справки). Из отзыва - person Wai Ha Lee; 28.04.2019