Angular 6 个测试 - Jasmine - 模拟链式承诺
Angular 6 testing - Jasmine - mock chained promises
我的服务中有一个方法 register()
我想测试一下。我的断言是调用了注入服务中的另一个方法。让我们更深入地研究我的代码:
服务
export class OAuthRegistrationService {
constructor(private afAuth: AngularFireAuth,
private afs: AngularFirestore) {
}
public register(register: RegisterDataModel): Promise<void | string> {
return this.afAuth.auth.createUserWithEmailAndPassword(register.email, register.password)
.then(() => {
const user = this.afAuth.auth.currentUser;
this.setUser(user, register).then(() =>
user.sendEmailVerification().then(() => 'Please verify your email').catch((err) => err));
}).catch((err: FirebaseErrorModel) => err.message);
}
}
现在,在我的单元测试中,我想断言 sendEmailVerification
已被调用。现在我需要正确模拟上面调用的 pomises,以检查是否已调用此方法。
规范文件/单元测试
describe('OAuthRegistrationService', () => {
let service: OAuthRegistrationService;
// stubs
const afAuthStub = {
auth: {
sendEmailVerification(): Promise<void> {
return new Promise<void>(resolve => resolve());
},
createUserWithEmailAndPassword(): Promise<void> {
return new Promise<void>(resolve => resolve());
},
currentUser: {
uid: 'blub'
}
}
};
const afsStub = {
doc(path: string) {
return {
set() {
return path;
}
};
}
}
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
{provide: AngularFireAuth, useValue: afAuthStub},
{provide: AngularFirestore, useValue: afsStub},
OAuthRegistrationService
]
});
service = TestBed.get(OAuthRegistrationService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
it('should send email verification', () => {
const register: RegisterDataModel = new RegisterDataModel('username', 'abc@email.com', 'password', null, null);
const mock = TestBed.get(AngularFireAuth);
const spy = spyOn(afAuthStub.auth, 'sendEmailVerification').and.callThrough();
spyOn(afAuthStub.auth, 'createUserWithEmailAndPassword').and.callThrough();
mock.auth = afAuthStub.auth;
service.register(register).then(() => {
expect(spy).toHaveBeenCalled();
});
});
});
Jasmines and.callTrough
允许我调用 Promise .then()
方法并转到我测试方法的下一步。但不知何故,我的控制台显示:我的间谍从未被调用过。有人知道吗,我在这里做错了什么?
您的存根略有错误,sendEmailVerification()
方法属于 currentUser
属性。
const afAuthStub = {
auth: {
createUserWithEmailAndPassword(): Promise<void> {
return new Promise<void>(resolve => resolve());
},
currentUser: {
uid: 'blub',
sendEmailVerification(): Promise<void> {
return new Promise<void>(resolve => resolve());
},
}
}
};
...
const spy = spyOn(afAuthStub.auth.currentUser, 'sendEmailVerification')
这是测试通过的StackBlitz。
我的服务中有一个方法 register()
我想测试一下。我的断言是调用了注入服务中的另一个方法。让我们更深入地研究我的代码:
服务
export class OAuthRegistrationService {
constructor(private afAuth: AngularFireAuth,
private afs: AngularFirestore) {
}
public register(register: RegisterDataModel): Promise<void | string> {
return this.afAuth.auth.createUserWithEmailAndPassword(register.email, register.password)
.then(() => {
const user = this.afAuth.auth.currentUser;
this.setUser(user, register).then(() =>
user.sendEmailVerification().then(() => 'Please verify your email').catch((err) => err));
}).catch((err: FirebaseErrorModel) => err.message);
}
}
现在,在我的单元测试中,我想断言 sendEmailVerification
已被调用。现在我需要正确模拟上面调用的 pomises,以检查是否已调用此方法。
规范文件/单元测试
describe('OAuthRegistrationService', () => {
let service: OAuthRegistrationService;
// stubs
const afAuthStub = {
auth: {
sendEmailVerification(): Promise<void> {
return new Promise<void>(resolve => resolve());
},
createUserWithEmailAndPassword(): Promise<void> {
return new Promise<void>(resolve => resolve());
},
currentUser: {
uid: 'blub'
}
}
};
const afsStub = {
doc(path: string) {
return {
set() {
return path;
}
};
}
}
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
{provide: AngularFireAuth, useValue: afAuthStub},
{provide: AngularFirestore, useValue: afsStub},
OAuthRegistrationService
]
});
service = TestBed.get(OAuthRegistrationService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
it('should send email verification', () => {
const register: RegisterDataModel = new RegisterDataModel('username', 'abc@email.com', 'password', null, null);
const mock = TestBed.get(AngularFireAuth);
const spy = spyOn(afAuthStub.auth, 'sendEmailVerification').and.callThrough();
spyOn(afAuthStub.auth, 'createUserWithEmailAndPassword').and.callThrough();
mock.auth = afAuthStub.auth;
service.register(register).then(() => {
expect(spy).toHaveBeenCalled();
});
});
});
Jasmines and.callTrough
允许我调用 Promise .then()
方法并转到我测试方法的下一步。但不知何故,我的控制台显示:我的间谍从未被调用过。有人知道吗,我在这里做错了什么?
您的存根略有错误,sendEmailVerification()
方法属于 currentUser
属性。
const afAuthStub = {
auth: {
createUserWithEmailAndPassword(): Promise<void> {
return new Promise<void>(resolve => resolve());
},
currentUser: {
uid: 'blub',
sendEmailVerification(): Promise<void> {
return new Promise<void>(resolve => resolve());
},
}
}
};
...
const spy = spyOn(afAuthStub.auth.currentUser, 'sendEmailVerification')
这是测试通过的StackBlitz。