如何测试与Firebase交互的服务?

时间:2016-12-13 18:04:38

标签: angular firebase firebase-realtime-database angularfire2

从Firebase获取数据的惯例似乎是创建一个在内部使用AngularFire的服务类。然后,在您的应用程序的组件中,您可以注入并使用该服务。这使您可以在单元测试组件时轻松模拟服务。

但是,我仍然不清楚如何测试实际的服务本身。

举个例子,假设我在Firebase中有一个todo list节点,我有一个简单的服务可以抓取所有todos,如下所示:

import { Injectable } from '@angular/core';
import { AngularFire } from 'angularfire2';

@Injectable()
export class TodoService {
  constructor(private af: AngularFire) { }

  getAll(): FirebaseListObservable<any[]> {
    return this.af.database.list('todos');
  }
}

您将如何测试此服务是否符合预期?

2 个答案:

答案 0 :(得分:5)

Reaz在他的回答中推荐了MockFirebase。但是,MockFirebase不能与Firebase 3一起使用。有一个名为firebase-mock的库,它似乎是由一些与MockFirebase相同的人开发的。这增加了MF,增加了Firebase 3支持,但它doesn't appear to play nicely with WebPack yet

这是我最终做的事情:

我突然想到L = [['a1',2],['a1',3],['a1',1],['b1',4],['b1',2],['b1',6],['c1',2], ...] d = {} for k,v in L: d[k] = max(d.get(k, -float('inf'), v) 继承自RXJS的FirebaseListObservable。所以,你可以嘲笑对Observable的AngularFire调用并让它返回你自己的Observable。

一些示例代码显示了这一点:

list

todos.service.spec.ts

let fixtureTodos = [ { 'text': 'Get milk' }, { 'text': 'Take out the trash' }, { 'text': 'Get gas for the car' }, { 'text': 'Pay parking ticket' }, { 'text': 'Pick up dry cleaning' }, ]; let angularFireDatabaseStub = { list: () => {} }; let mockTodos$ = Observable.of(fixtureTodos); describe('TodosService', () => { beforeEach(() => { spyOn(angularFireDatabaseStub, 'list').and.returnValue(mockTodos$); TestBed.configureTestingModule({ providers: [ TodosService, { provide: AngularFireDatabase, useValue: angularFireDatabaseStub }, ] }); }); it('#getAll', inject([TodosService], (service: TodosService) => { let todos$ = service.getAll(); todos$.subscribe(todos => { expect(todos[0].text).toEqual(fixtureTodos[0].text); expect(todos[0]).toEqual(jasmine.any(Todo)); }); })); });

todos.service.ts

@Injectable() export class TodosService { constructor(public db: AngularFireDatabase) { } getAll(): Observable<Todo[]> { return this.db.list('todos').map(arr => { return arr.map(t => new Todo(t.text)); }); } }

todo.model.ts

答案 1 :(得分:1)

这个问题主要是以意见为基础的,因此,我只是在这里提出意见。

我会在Firebase中创建一个测试节点,其中包含与我的开发数据库完全相同的模型。因此,在编写单元测试时,我会插入一些数据并再次检索它们以匹配之前插入的数据。

基本上,Firebase将数据存储在Json结构中。所以我会写一些测试Json todo条目。我不会模拟Firebase参考对象或连接,因为这基本上是第三方软件。我会在运行单元测试时与Firebase建立真正的连接,插入一些数据并将其检索回来并与我之前插入的数据匹配。那将是我的方法。

<强>更新

是的,您对持续集成有一些有效的顾虑。老实说,我之前没有做过这样的事情,而是团队和CI服务器。我不能保证顺利的体验。

在寻找更好的解决方案时,我发现MockFirebase可能符合您的目的。你可以看看。

我想参考this answer,他建议将Firebase调用保存在库中。但是,这不考虑CI服务器。