Updating with some new attempts
I've tried several different approaches, and I'm obviously missing something fundamental on how to avoid this error and mock out this function. I've updated the mock and spec.ts with what I'm currently working with.
I'm trying to mock/test SendVerificationMail()
from my AuthService, which starts by calling the AngularFireAuth method currentUser
which returns an angularFire User object, which you can then use to call sendEmailVerification(). I've tried a few different mocking methods, but I just end up with the errors below because it can't find user.sendEmailVerification
Error
Error: Uncaught (in promise): TypeError: user.sendEmailVerification is not a function TypeError: user.sendEmailVerification is not a function
AuthService
SendVerificationMail() {
return this.afAuth.currentUser
.then((user: any) => {user.sendEmailVerification(),})
.then(() => {
this.router.navigate(['verify-email-address']);
});
}
AngularFireAuth Mock File
import { User } from '../shared/interface/user';
import { of } from 'rxjs';
import { userCredential } from './mock_userCredential';
const authState: User = {
uid: 'fakeuser',
email: 'test@test.com',
emailVerified: true
};
export const AngularFireAuthMock: any = {
returnedUser: {
sendEmailVerification: () => {
return Promise.resolve()
}
},
createUserWithEmailAndPassword: () => {
return Promise.resolve(userCredential)
},
signOut: () => {
return Promise.resolve()
},
signInWithEmailAndPassword: () => {
return Promise.resolve()
},
sendPasswordResetEmail: () => {
return Promise.resolve()
},
get authState() {
return of(authState);
},
get user() {
return this.authState;
},
get currentUser() {
return Promise.resolve(userCredential)
}
}
auth.service.spec.ts
it('SendVerificationMail() - Functions', fakeAsync(() => {
// let returnedUser: any = {
// sendEmailVerification: () => {
// return Promise.resolve()
// }
// }
// let returnedUser = {
// sendEmailVerification: jasmine.createSpy('Promise.resolve()')
// }
// spyOn(returnedUser, 'sendEmailVerification').and.callThrough()
spyOn(AngularFireAuthMock.returnedUser, 'sendEmailVerification').and.callThrough()
tick()
service.SendVerificationMail()
}));
I am not sure what userCredential
is but I would do the following:
get currentUser() {
return Promise.resolve({
sendEmailVerification: () => Promise.resolve(null);
});
}
Make currentUser
return a promise that's an object where it resolves to a promise of null.
Edit: To assert sendEmailVerification
, do the following:
// Eventually, sendEmailVerificationSpy will be a Spy function
let sendEmailVerificationSpy: jasmine.Spy;
...
// Assign sendEmailVerificationSpy to be a spy function
sendEmailVerificationSpy = jasmine.createSpy();
// And then modify `get currentUser()` to be:
get currentUser() {
// Call the spy on sendEmailVerification.
return Promise.resolve({
sendEmailVerification: () => sendEmailVerificationSpy(),
});
}
...
// And then, assert that it was called.
expect(sendEmailVerificationSpy).toHaveBeenCalled();
You have to be strategic in when you declare and assign the spy function.