Search code examples
angularngrx-effectsangular-testjasmine-marbles

How to trigger an error with 'ngrx effects' when testing with angular


Here is my effects:

 getAssessmentPeriods$: Observable<Action> = createEffect(() =>
        this.actions$.pipe(
            ofType(courseAttributeActions.getAssessmentPeriod_CR),
            switchMap(() => this.courseAttributeService.getAssessmentPeriods()
                .pipe(
                    map((value: any) => {
                        return courseAttributeActions.getAssessmentPeriodSuccess_CR({ payload: value });
                    }),
                    catchError(error => of(courseAttributeActions.LoadFailure_CR(error)))
                ))
        ));

spec file: happy scenario works fine:

it('should return a cold observable of getAssessmentPeriodSuccess_CR', () => {

        const fakeData: any = [];

        const start = courseAttributeActions.getAssessmentPeriod_CR();
        const completion = courseAttributeActions.getAssessmentPeriodSuccess_CR({ payload: fakeData });

        jest.spyOn(service, 'getAssessmentPeriods').mockImplementation(() => of(fakeData));

        actions = hot('--a-', { a: start });
        const expected = cold('--(b)', { b: completion });

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

    });

spec file: error scenario not works:

 it('should return a cold observable of LoadFailure_CR error ', () => {

        const errors: any = throwError((new Error('Network error')));

        const start = courseAttributeActions.getAssessmentPeriod_CR();
        const completionError = courseAttributeActions.LoadFailure_CR({error:errors});

        jest.spyOn(service, 'getAssessmentPeriods').mockImplementation(() => of(errors));

        actions = hot('--a-', { a: start });
        const expected = cold('--(b)', { b: completionError });

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

    });

In error scenario how to trigger the error in service? actually i am sending an from spy. but still i am getting success message called.

getting error in console like:

- Expected
    + Received

    @@ -4,14 +4,14 @@
          "notification": Notification {
            "error": undefined,
            "hasValue": true,
            "kind": "N",
            "value": Object {
    -         "error": Observable {
    +         "payload": Observable {
                "_isScalar": false,
                "_subscribe": [Function anonymous],
              },
    -         "type": "[candidate-registration-management] LoadFailure_CR",
    +         "type": "[candidate-registration-management_CR] getAssessmentPeriodSuccess",
            },
          },
        },
      ]

      69 |         const expected = cold('--(b)', { b: completionError });
      70 |
    > 71 |         expect(effects.getAssessmentPeriods$).toBeObservable(expected);

How to fix the error? is it really required to write 2 separate 'it' function for 1 effect? Look for help. thanks in advance.


Solution

  • throwError is the same as

    return new Observable(subscriber => subscriber.error(error));
    

    So, by doing mockImplementation(() => of(errors)); you'll have an observable(e.g of) which emits another observable(a next notification).

    In order for the error to occur, the getAssessmentPeriods observable must emit an error notification, so I think you can solve it by doing:

    .mockImplementation(() => errors)