It seems like the convention for grabbing data from Firebase is to create a service class that uses AngularFire internally. Then, in your app's components, you can inject and use the service. This allows you to easily mock out the service when unit testing your components.
But, I'm still not clear on how to go about testing the actual service itself.
As an example, say I have a todo list
node in Firebase and I have a simple service that grabs all of the todos
, like so:
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');
}
}
How would you go about testing that this service does what you expect?
Reaz recommended MockFirebase in his answer. However, MockFirebase doesn't work with Firebase 3. There is a library called firebase-mock, which appears to be developed by some of the same people as MockFirebase. This augments MF, adding Firebase 3 support, however it doesn't appear to play nicely with WebPack yet.
It occurred to me that FirebaseListObservable
inherits from RXJS's Observable
. So, you can just mock out the AngularFire call to list
and have it return your own Observable.
Some example code showing this in action:
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
export class Todo {
constructor(public text: string) {}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With