I'm trying to make sure the catch block of a function on my service is covered, and I just can't quite get it to work.
I've tried a couple of different ways. In version 1, it seems cleaner but I don't think it's working as well as version 2. In version 2, I can see the console.log() I put in the catch block triggering, so I know the spy etc is working. I'm obviously missing something to connect everything.
AuthService Function
SignUp(email: any, password: any, firstName: string, lastName: string) {
return this.afAuth
.createUserWithEmailAndPassword(email, password)
.then((userCredential) => {
this.SendVerificationMail();
this.SetUserData(userCredential.user, firstName, lastName);
})
.catch((error) => {
console.log('errorLog: ', error)
window.alert(error.message);
});
}
auth.service.spec.ts Version 1
it('SignUp() - Errors', async () => {
spyOn(AngularFireAuthMock, 'createUserWithEmailAndPassword').and.callFake(() => { throw new Error('auth/expired-action-code') })
expect (service.SignUp('test@test.com', '123456', 'Name', 'Two')).toThrowError('auth/expired-action-code');
});
Version 1 Error
Chrome 126.0.0.0 (Windows 10) AuthService SignUp() - Errors FAILED
Error: auth/expired-action-code
at Object.<anonymous> (src/app/shared/services/auth.service.spec.ts:58:93)
at <Jasmine>
at AuthService.SignUp (src/app/shared/services/auth.service.ts:41:8)
at UserContext.<anonymous> (src/app/shared/services/auth.service.spec.ts:59:21)
at Generator.next (<anonymous>)
at asyncGeneratorStep (node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js:3:1)
Chrome 126.0.0.0 (Windows 10): Executed 5 of 5 (1 FAILED) (0.03 secs / 0.016 secs)
auth.service.spec.ts Version 2
it('SignUp() - Errors', async () => {
spyOn(AngularFireAuthMock, 'createUserWithEmailAndPassword').and.callFake(() => Promise.reject(new Error('auth/expired-action-code')))
expect (service.SignUp('test@test.com', '123456', 'Name', 'Two')).toThrowError('auth/expired-action-code');
});
Version 2 Error
Chrome 126.0.0.0 (Windows 10) AuthService SignUp() - Errors FAILED
Error: <toThrowError> : Actual is not a Function
Usage: expect(function() {<expectation>}).toThrowError(<ErrorConstructor>, <message>)
at <Jasmine>
at UserContext.<anonymous> (src/app/shared/services/auth.service.spec.ts:59:71)
at Generator.next (<anonymous>)
at asyncGeneratorStep (node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js:3:1)
at _next (node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js:22:1)
at executor (node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js:27:1)
at new ZoneAwarePromise (node_modules/zone.js/fesm2015/zone.js:2662:25)
at UserContext.<anonymous> (node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js:19:1)
LOG: 'errorLog: ', Error: auth/expired-action-code
Error: auth/expired-action-code
at Object.<anonymous> (http://localhost:9876/_karma_webpack_/webpack:/src/app/shared/services/auth.service.spec.ts:58:100)
at SpyStrategy.exec (http://localhost:9876/base/node_modules/karma-jasmine/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?86d98e11f43f2c8cfac9fb4806ed6c0aced74cbe:9310:39)
Reject the promise and return an object with message property, but do not throw an error. Then spyOn window
alert
method and check if it's called:
it('SignUp() - Errors', fakeAsync(() => {
spyOn(AngularFireAuthMock, 'createUserWithEmailAndPassword').and.callFake(() => Promise.reject({ message: 'auth/expired-action-code' }));
spyOn(window, 'alert');
service.SignUp('test@test.com', '123456', 'Name', 'Two');
flush();
expect (window.alert).toHaveBeenCalledWith('auth/expired-action-code');
}));