Jasmine .and.throwError() is not caught by .catch in original code
Asked Answered
B

3

8

I'm writing a test for a function, and have to trigger the .catch part of that function, but Jasmine's spiesfor some reason can't do that. Method to be tested:

foo(){
doStuff()
.catch((error) => {
    //stuff I still have to test
    bar()
})

}

doStuff() returns a Promise (hence the .catch-Setup), but for this test it's supposed to throw an error.

Here is my test:

it('tests the error handling of foo',(done) =>{
spyOn(object,'foo').and.throwError('Test Error');

object.foo();

expect(object.bar).toHaveBeenCalled();
done();

});

Is the way I'm approaching this wrong? Is that an error with Jasmine? (Google didn't find anything) [I stick to the (done) setup because almost all other tests are async and I want to keep the style]

[I cannot change the code to be tested]

Bachelor answered 8/3, 2018 at 12:1 Comment(0)
C
5

If you call and.throwError(...); you throw the error within the test method.

You can try to return a Promise rejection instead:

spyOn(object, 'foo').and.rejectWith(new Error('Test Error'));

Chaulmoogra answered 9/7, 2020 at 18:54 Comment(0)
D
11

I think I had a problem similar to yours. Here's how I solved it

import { throwError } from 'rxjs';

it(`...`, fakeAsync(() => {
    spy = spyOn(authService, 'signIn').and.returnValue(throwError(loginError));
    /* do things */
    expectSnackbar('error', loginError);
    expect(authService.ensureLogin).toHaveBeenCalled(); 
}));

Here's how the call to the signIn method looks like:

return this.authService
    .signIn(payload.email, payload.password)
    .map((userId: string) => {
        // Whatever
    })
    .catch(error => {
        // Do something with the error
    });

And how the thrown error looks like inside signIn

public signIn(email: string, password: string): Observable<string> {
    return this.jsonServerService.get('login').pipe(
        map(users => {
            if (/* valid */) {
                return user.userId;
            } else {
                throw new Error('Error');
            }
        }),
    );
}
Dignadignified answered 3/10, 2018 at 17:16 Comment(1)
What is V. Where is that comes from?Uralaltaic
C
5

If you call and.throwError(...); you throw the error within the test method.

You can try to return a Promise rejection instead:

spyOn(object, 'foo').and.rejectWith(new Error('Test Error'));

Chaulmoogra answered 9/7, 2020 at 18:54 Comment(0)
R
2

and.throwError does not exist when I try it. Maybe I'm using an old version of jasmine.

I got it to work by returning a promise rejection:

and.returnValue(Promise.reject({response: {status: 401}}))
Ragen answered 22/2, 2022 at 11:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.