I\'m trying to set up unit tests for a sample Angular 2 app using AngularFire 2 auth, the component is fairly simple:
import { Component } from \'@angular/core\'
Similar to @jan, I made a mock using some utility functions:
import {AngularFireAuth} from '@angular/fire/auth';
import {AngularFireDatabase} from '@angular/fire/database';
import {auth} from 'firebase/app';
import { Observable, of, Subscription } from 'rxjs';
/**
* Mocks the Firebase auth by automatically logging in.
*/
export const AngularFireAuthMock = jasmine.createSpy('signInWithEmailAndPassword')
.and.returnValue(Promise.resolve({uid: 'fakeuser'}));
/**
* Mocks an AngularFireDatabase that always returns the given data for any path.
*/
export function mockAngularFireDatabase(data): AngularFireDatabase {
return {
object: (path: string): any => {
return {
valueChanges() {
return of(data);
}
}
}
} as AngularFireDatabase;
}
and then you can use them in your spec like this:
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ TweakComponent ],
imports: [ MatDialogModule, RouterTestingModule ],
providers: [
{ provide: MAT_DIALOG_DATA, useValue: {} },
{ provide: AngularFireDatabase, useValue: mockAngularFireDatabase({testdata:'hi'})},
{ provide: AngularFireAuth, useValue: AngularFireAuthMock}
],
})
.compileComponents();
});
In this snippet:
beforeEach(() => addProviders([
AppComponent,
AngularFire
]);
You set (or override) the providers that will be used in your test.
That being said, you can create a different class, a mock if you will, and, using the { provide: originalClass, useClass: fakeClass }
notation, provide it instead of the AngularFire
actual class.
Something like this:
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
]);
And the AngularFire
s in your tests will be AngularFireMock
s.
hope it is not off the topic, but the easiest solution I have found how to mock the FirebaseDatabase.
var object = function() {
var obj = { valueChanges() {
return of({data:'data'});
}
}
return obj;
}
providers: [..., { provide : AngularFireDatabase,
useValue: {object : object }} ]
instead of data:'data' you can mock whatever data you need. The functions can be modified as you wish.