NgRX createEffect 调用中的模拟 catchError

Mock catchError in NgRX createEffect call

我目前正在为以下调度事件编写测试:

@Injectable()
export class AuthEffects {
  signIn$ = createEffect(() =>
    this.actions$.pipe(
      ofType(AuthActions.signIn),
      switchMap((action) =>
        from(this.loginService.signIn(action.email, action.password, action.redirectTo)).pipe(
          map(() => AuthActions.signInSuccess()),
          catchError((err: Error) =>
            of(
              AuthActions.signInError({
                message: err.message,
              })
            )
          )
        )
      )
    )
  );

  constructor(
    private actions$: Actions,
    private loginService: LoginService
  ) {}
}

测试如下:

describe('AuthEffects', () => {
  let effects: AuthEffects;
  let actions$: Observable<Action>;
  let mockLoginService: LoginService;
  let mockSupabaseService: SupabaseService;

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [provideMockActions(() => actions$), AuthEffects],
    });
    effects = TestBed.inject(AuthEffects);
    mockLoginService = TestBed.inject(LoginService);
    mockSupabaseService = TestBed.inject(SupabaseService);
  });
  describe('signIn$', () => {
    it('should allow sign in', () => {
      const payload = { email: 'test@hotmail.com', password: '123', redirectTo: 'dashboard' };
      actions$ = cold('a', { a: AuthActions.signIn(payload) });
      jest.spyOn(mockSupabaseService, 'signIn').mockImplementation(() => Promise.resolve([]));
      effects.signIn$.subscribe(() => {
        expect(mockLoginService.signIn).toHaveBeenCalled();
      });
    });

    it('should not allow sign in', () => {
      const payload = { email: 'test@hotmail.com', password: '123', redirectTo: 'dashboard' };
      const mockError = { name: 'test', message: 'test' };
      actions$ = cold('a', { a: AuthActions.signIn(payload) });
      jest.spyOn(mockSupabaseService, 'signIn').mockImplementation(() => {
        return Promise.reject(mockError);
      });
      effects.signIn$.subscribe(() => {
        expect(mockLoginService.signIn).toHaveBeenCalled();
      });
    });
  });
});

我在模拟覆盖 catchError 方法所需的输出时遇到问题。每次我 运行 测试时,我都会收到以下错误:

console.error
Unhandled Promise rejection: { name: 'test', message: 'test' } ; Zone: ProxyZone ; Task: null ; Value: { name: 'test', message: 'test' } undefined

我该如何解决这个问题?

让您的 signIn 模拟调用 rxjs throwError 运算符:

jest.spyOn(mockSupabaseService, 'signIn').mockImplementation(() => throwError(mockError));