I'm having a really hard time to try to understand how TestBed works and how to use it to mock data retrieval (via AngularFire2 i.e. observables)/pushing in an offline unit test.If someone could provide a simple example to look at it would make things so much easier.
Below is (part of) StateService. I then inject this service in another component and print out the graphModules names, e.g.
graph-modules.component.html
<div *ngFor="let module of s.graphModules$ | async"><div class="module-card">{{module.name}}</div></div>
graph-modules.component.ts
constructor(public s: StateService){}
state.service.ts
@Injectable()
export class StateService {
graphModules$: FirebaseListObservable<any>;
private auth;
constructor(public af: AngularFire) {
af.auth.subscribe(
latestAuth => {
this.graphModules$ = af.database.list('/graphModules', {
query: {
orderByChild: 'archived',
equalTo: false
}
});
},
errors => {
this.auth = {uid: 'AUTH PROBLEMS'};
throw 'Problems authenticating';
}
);
}
saveToDB(key: string, value: any) {
this.af.database.list('/graphModules').update(key, value);
...
}
...
}
What I want like to test is
1) given a mock/stub of "graphModules", the correct number of .card-module will be printed to DOM.
2) after updating one of the modules with s.saveToDB(), the names are updated in the DOM
On a side note, if you have other comments about my "architecture" for data retrieval that'd be most welcome too :)
Many thanks!
EDIT:
Ok, I found out how to fix number 1. The test is passing correctly. Question 2 is yet to be answered. The spec file now looks like this:
graph-modules.component.spec.ts
class MockStateService {
public graphModules$: Observable<GraphModule[]>;
constructor () {
this.graphModules$ = Observable.of<GraphModule[]>([
{
name: 'first',
...
},
{
name: 'second',
...
}
]);
}
updateGraphModule(key: string, value: any) {
// Not sure what to put here in order to emit new value on graphModules$
}
}
describe('ModulesComponent', () => {
let fixture: ComponentFixture<ModulesComponent>;
beforeEach(() => {
this.service = new MockStateService();
TestBed.configureTestingModule({
imports: [AppModule],
providers: [{provide: StateService, useValue: this.service }]
});
fixture = TestBed.createComponent(ModulesComponent);
});
it('should print out two graphModules', async(() => {
fixture.whenStable().then(() => {
fixture.detectChanges();
const test = fixture.nativeElement.querySelectorAll('.module-card');
expect(fixture.nativeElement.querySelectorAll('.module-card').length).toBe(2);
});
}));
it('should retrieve new data from observer and update DOM when the first graph-module has been given a new name', async(() => {
fixture.whenStable().then(() => {
fixture.detectChanges();
this.service.updateGraphModule(0, {name: 'new name'});
// What should I write here to test if the DOM is correctly updated?
});
}));
}));
});