Search code examples
angularjasminengxs

Testing NGXS exceptions with jasmine


I'm trying to write unit tests for the actions performed by our Angular application through ngxs. In one of my tests, I'm expecting the action to throw an Error. I tried using

expect(function() {store.dispatch(new MyAction(param));}).toThrowError();

but it gives me the message "Expected function to throw an Error." even though I see the Error in my console. After this failure I tried the following:

let errorMessage;
try {
    store.dispatch(new MyAction(param));
} catch (error) {
    console.log("In catch!");
    errorMessage = error;
}
expect(errorMessage).toBe(myErrorMessage);

Once again I see the Error in my console, but I don't see the "In catch!" console.log in my catch clause. After some research I found out that angular has it's own ErrorHandler, which catches this Error before jasmine can do something with it. How can you prevent this?


Solution

  • The answer is: mock the angular ErrorHandler using jasmine! First create a spy:

    export const errorHandlerSpy = () => jasmine.createSpyObj('ErrorHandler', {
        handleError: undefined
    });
    

    use this spy as a provider in your tests:

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            imports: [NgxsModule, /*other imports*/],
            providers: [
                { provide: ErrorHandler, useFactory: errorHandlerSpy }
            ]
        }).compileComponents();
    }));
    

    check for thrown Errors like this:

    const errorHandler = TestBed.get(ErrorHandler);
    store.dispatch(new MyAction(param));
    expect(errorHandler.handleError).toHaveBeenCalledWith(new Error('Your error message'));
    

    I hope I saved someone else the headache of figuring this out!