Angular firebase - 使用 angularFireAuth 对服务进行单元测试
Angular firebase - Unit testing a service using angularFireAuth
我有一个核心服务,它获取 firebase.auth
obj 的实例并 returns 它带有 getter。它很简单,如下所示:
export class AuthService {
...
constructor(private afAuth: AngularFireAuth,
private afs: AngularFirestore) {
...
}
public getAuthInstance(): FirebaseAuth {
return this.afAuth.auth;
}
}
现在我有一个 LoginService 需要 AuthService 来登录我的应用程序。
export class LoginService {
constructor(private authService: AuthService) {
}
public login(email, password): Promise<UserCredential | string> {
return this.authService.getAuthInstance().signInWithEmailAndPassword(email, password)
.catch(() => Promise.reject('Login failed.'));
}
也不算太复杂。但现在我想测试我的登录组件。 - 特别是 login
方法。我无法模拟 signInWithEmailAndPassword
。我基本上尝试了一切:
jasmine.spies
- 自己创建的假对象。
测试 class 如下所示:
...
const authStub: AuthService = jasmine.createSpyObj('AuthService', ['getAuthInstance']);
const fireStub = {
auth: {
signInWithEmailAndPassword() {
return Promise.resolve();
}
}
};
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
{provide: AuthService, useValue: authStub},
{provide: AngularFireAuth, useValue: fireStub},
LoginService
]
});
});
const spy = it('should call signInWithPasswordAndEmail', inject([LoginService], (service: LoginService) => {
(<jasmine.Spy>authStub.getAuthInstance).and.returnValue({username: 'test'});
spyOn(fireStub.auth, 'signInWithEmailAndPassword').and.callThrough();
service.login(email, password).then(() => expect(spy).toHaveBeenCalledTimes(1));
}));
谁能帮我把这个该死的测试改成绿色? xD^^
错误消息。抛出的是:this.getAuthInstance().signInWithEmail.... 不是函数
经过反复试验,我用 AngularFireAuth
和 AngularFireStore
间接模拟了 AuthService
,测试配置如下所示:
describe('LoginService', () => {
const email: string = 'email';
const password: string = 'password';
const authStub: any = {
authState: {},
auth: {
signInWithEmailAndPassword() {
return Promise.resolve();
}
}
};
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
{provide: AngularFireAuth, useValue: authStub},
{provide: AngularFirestore},
LoginService
]
});
authStub.authState = of(null);
});
it('should call signInWithPasswordAndEmail', inject([LoginService], (service: LoginService) => {
const mock = TestBed.get(AngularFireAuth);
const spy = spyOn(authStub.auth, 'signInWithEmailAndPassword').and.callThrough();
mock.auth = authStub.auth;
service.login(email, password);
expect(spy).toHaveBeenCalledWith(email, password);
}));
});
它完成了工作。如果有人有更好的解决方案,我很乐意知道。
我有一个核心服务,它获取 firebase.auth
obj 的实例并 returns 它带有 getter。它很简单,如下所示:
export class AuthService {
...
constructor(private afAuth: AngularFireAuth,
private afs: AngularFirestore) {
...
}
public getAuthInstance(): FirebaseAuth {
return this.afAuth.auth;
}
}
现在我有一个 LoginService 需要 AuthService 来登录我的应用程序。
export class LoginService {
constructor(private authService: AuthService) {
}
public login(email, password): Promise<UserCredential | string> {
return this.authService.getAuthInstance().signInWithEmailAndPassword(email, password)
.catch(() => Promise.reject('Login failed.'));
}
也不算太复杂。但现在我想测试我的登录组件。 - 特别是 login
方法。我无法模拟 signInWithEmailAndPassword
。我基本上尝试了一切:
jasmine.spies
- 自己创建的假对象。
测试 class 如下所示:
...
const authStub: AuthService = jasmine.createSpyObj('AuthService', ['getAuthInstance']);
const fireStub = {
auth: {
signInWithEmailAndPassword() {
return Promise.resolve();
}
}
};
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
{provide: AuthService, useValue: authStub},
{provide: AngularFireAuth, useValue: fireStub},
LoginService
]
});
});
const spy = it('should call signInWithPasswordAndEmail', inject([LoginService], (service: LoginService) => {
(<jasmine.Spy>authStub.getAuthInstance).and.returnValue({username: 'test'});
spyOn(fireStub.auth, 'signInWithEmailAndPassword').and.callThrough();
service.login(email, password).then(() => expect(spy).toHaveBeenCalledTimes(1));
}));
谁能帮我把这个该死的测试改成绿色? xD^^ 错误消息。抛出的是:this.getAuthInstance().signInWithEmail.... 不是函数
经过反复试验,我用 AngularFireAuth
和 AngularFireStore
间接模拟了 AuthService
,测试配置如下所示:
describe('LoginService', () => {
const email: string = 'email';
const password: string = 'password';
const authStub: any = {
authState: {},
auth: {
signInWithEmailAndPassword() {
return Promise.resolve();
}
}
};
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
{provide: AngularFireAuth, useValue: authStub},
{provide: AngularFirestore},
LoginService
]
});
authStub.authState = of(null);
});
it('should call signInWithPasswordAndEmail', inject([LoginService], (service: LoginService) => {
const mock = TestBed.get(AngularFireAuth);
const spy = spyOn(authStub.auth, 'signInWithEmailAndPassword').and.callThrough();
mock.auth = authStub.auth;
service.login(email, password);
expect(spy).toHaveBeenCalledWith(email, password);
}));
});
它完成了工作。如果有人有更好的解决方案,我很乐意知道。