如何在单元测试中模拟AngularFire 2服务?

Jav*_*eva 15 unit-testing jasmine karma-jasmine angularfire2 angular

我正在尝试使用AngularFire 2 auth为示例Angular 2应用程序设置单元测试,该组件非常简单:

import { Component } from '@angular/core';
import { AngularFire, AuthProviders } from 'angularfire2';

@Component({
  moduleId: module.id,
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.css']
})
export class AppComponent {
  isLoggedIn: boolean;

  constructor(public af: AngularFire) {
    this.af.auth.subscribe(auth => {
      if (auth) {
        this.isLoggedIn = true;
      } else {
        this.isLoggedIn = false;
      }
    });
  }

  loginWithFacebook() {
    this.af.auth.login({
      provider: AuthProviders.Facebook
    });
  }

  logout() {
    this.af.auth.logout();
  }
}
Run Code Online (Sandbox Code Playgroud)

我做的是周围包裹login,并logout在AngularFire方法,所以我想使用一个模拟检查,如果这些方法被称为,但我不知道从哪里开始,我试图做我的spec文件如下:

import { provide } from '@angular/core';
import { AngularFire } from 'angularfire2';
import {
  beforeEach, beforeEachProviders,
  describe, xdescribe,
  expect, it, xit,
  async, inject
} from '@angular/core/testing';
import { AppComponent } from './app.component';

spyOn(AngularFire, 'auth');

beforeEachProviders(() => [
  AppComponent,
  AngularFire
]);

describe('App Component', () => {
  it('should create the app',
    inject([AppComponent], (app: AppComponent) => {
      expect(app).toBeTruthy();
    })
  );

  it('should log user in',
    inject([AppComponent], (app: AppComponent) => {
      expect(app.fb.auth.login).toHaveBeenCalled();
    })
  );

  it('should log user out',
    inject([AppComponent], (app: AppComponent) => {
      expect(app.fb.auth.logout).toHaveBeenCalled();
    })
  );
});
Run Code Online (Sandbox Code Playgroud)

但是我不确定如何模拟loginlogout方法,因为它们是auth属性的一部分,有没有办法模拟auth,还有返回loginlogout方法?

acd*_*ior 16

在这个片段中:

beforeEach(() => addProviders([
  AppComponent,
  AngularFire
]);
Run Code Online (Sandbox Code Playgroud)

您设置(或覆盖)将在测试中使用的提供程序.

话虽这么说,你可以创建一个不同的类,如果你愿意,可以创建一个模拟,并使用{ provide: originalClass, useClass: fakeClass }符号提供它而不是AngularFire实际的类.

像这样的东西:

class AngularFireAuthMock extends AngularFireAuth {           // added this class
  public login() { ... }
  public logout() { ... }
}

class AngularFireMock extends AngularFire {                   // added this class
  public auth: AngularFireAuthMock;
}

beforeEach(() => addProviders([
  AppComponent,
  { provide: AngularFire, useClass: AngularFireMock }         // changed this line
]);
Run Code Online (Sandbox Code Playgroud)

AngularFire在测试中旨意是AngularFireMock秒.