【问题标题】:Angular firebase - Unit testing a service using angularFireAuthAngular firebase - 使用 angularFireAuth 对服务进行单元测试
【发布时间】:2019-01-24 11:17:23
【问题描述】:

我有一个核心服务,它获取firebase.auth obj 的实例并使用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
  • 自创假obj。

测试类如下:

  ...
  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.... 不是函数

【问题讨论】:

  • 能否提供测试运行者的错误信息?
  • 忘了说。现在更新了问题。

标签: angular unit-testing jasmine mocking angularfire2


【解决方案1】:

经过反复试验,我用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);
  }));
});

它完成了工作。如果有人有更好的解决方案,我会很高兴知道。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 2019-04-12
    • 1970-01-01
    • 2014-05-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多