Angular单元测试:模拟SendVerificationMail函数遇报错问题
问题根源
报错的核心原因是你Mock的AngularFireAuth.currentUser返回的是userCredential对象,但实际Firebase的currentUser返回的是带有sendEmailVerification方法的User实例。你的userCredential(推测)并没有这个方法,所以调用user.sendEmailVerification()时会抛出类型错误。
解决方案
1. 修正AngularFireAuthMock的currentUser返回值
把currentUser的返回值改成你已经定义好的returnedUser(该对象包含sendEmailVerification方法),而不是userCredential:
export const AngularFireAuthMock: any = { // ... 其他方法保持不变 get currentUser() { // 替换原来的userCredential,返回带sendEmailVerification的对象 return Promise.resolve(this.returnedUser) } }
2. 修复AuthService中的Promise链式调用问题
你的SendVerificationMail方法里第一个then的箭头函数写法有问题:大括号包裹的代码没有返回user.sendEmailVerification()的Promise,会导致第二个then跳过等待直接执行。修正为:
SendVerificationMail() { return this.afAuth.currentUser // 去掉大括号自动返回Promise;或者显式添加return关键字 .then((user: any) => user.sendEmailVerification()) .then(() => { this.router.navigate(['verify-email-address']); }); }
3. 完善测试逻辑
测试需要验证方法调用和路由跳转,同时正确处理异步逻辑:
it('SendVerificationMail() should trigger email verification and navigate', fakeAsync(() => { // Spy sendEmailVerification方法 const emailSpy = spyOn(AngularFireAuthMock.returnedUser, 'sendEmailVerification').and.returnValue(Promise.resolve()); // Spy router.navigate方法 const navigateSpy = spyOn(service['router'], 'navigate'); // 调用测试方法 service.SendVerificationMail(); // 等待所有异步Promise完成 tick(); // 验证方法是否被调用 expect(emailSpy).toHaveBeenCalled(); // 验证路由跳转是否触发 expect(navigateSpy).toHaveBeenCalledWith(['verify-email-address']); }));
额外说明
如果你的userCredential对象本身应该包含User实例(比如userCredential.user),那也可以调整currentUser的返回逻辑为Promise.resolve(userCredential.user),但前提是你要给userCredential.user添加sendEmailVerification方法。不过从你现有Mock的结构来看,直接返回returnedUser是最直接的解决方案。
内容的提问来源于stack exchange,提问作者Rusty Shackleford
相关产品推荐
相关产品推荐

