Attempting to test an Angular 2 component with fake dependencies has been a challenge.
Currently developing a simple TODO app using Ng2 and Redux, I have encountered a situation where one of my components includes an instance of the redux app store.
In order to mock this object and spy on its subscribe method, I have come up with the following solution:
import { TestComponentBuilder } from '@angular/compiler/testing';
import {HomeComponent} from './home.component';
import {provide} from '@angular/core';
import {
it,
expect,
inject,
describe,
async,
beforeEachProviders
} from '@angular/core/testing';
class MockAppStore {
title: String;
constructor() {
this.title = 'plouf';
}
subscribe(callback) {
callback();
}
}
describe('HomeComponent', () => {
beforeEachProviders(() => [
provide('AppStore', { useValue: MockAppStore })
]);
it('should call the dispatch method of the appStore', async(inject([TestComponentBuilder],
(tsb: TestComponentBuilder) => {
tsb.createAsync(HomeComponent).then((fixture) => {
// Given
const component = fixture.componentInstance;
spyOn(component.appStore, 'subscribe');
// When
fixture.detectChanges();
// then
expect(component.appStore.subscribe).toHaveBeenCalled();
});
})));
});
This is meant to test the following component :
import {Component, Inject} from '@angular/core';
@Component({
selector: 'as-home',
templateUrl: 'app/home/home.html',
styleUrls: [
'app/home/home.css'
]
})
export class HomeComponent {
appStore: any;
constructor( @Inject('AppStore') appStore: any) {
this.appStore = appStore;
this.appStore.subscribe(state => {
console.log(state);
});
}
}
Unfortunately, the test does not pass and the error message is not very clear:
PhantomJS 2.1.1 (Windows 8 0.0.0) HomeComponent should call the dispatch method of the appStore FAILED
invoke@C:/Project/angular2/kanboard/node_modules/zone.js/dist/zone.js:323:34
run@C:/Project/angular2/kanboard/node_modules/zone.js/dist/zone.js:216:50
C:/Project/angular2/kanboard/node_modules/zone.js/dist/zone.js:571:61
invokeTask@C:/Project/angular2/kanboard/node_modules/zone.js/dist/zone.js:356:43
runTask@C:/Project/angular2/kanboard/node_modules/zone.js/dist/zone.js:256:58
drainMicroTaskQueue@C:/Project/angular2/kanboard/node_modules/zone.js/dist/zone.js:474:43
invoke@C:/Project/angular2/kanboard/node_modules/zone.js/dist/zone.js:426:41
PhantomJS 2.1.1 (Windows 8 0.0.0): Executed 16 of 16 (1 FAILED) (0.48 secs / 0.518 secs)
Remapping coverage to TypeScript format...
Test Done with exit code: 1
[08:28:55] 'unit-test' errored after 7.27 s
[08:28:55] Error: 1
at formatError (C:\Project\angular2\kanboard\node_modules\gulp\bin\gulp.js:169:10)
...and so on...
If you have any insights on why the test is failing or have suggestions for best practices when mocking rxjs observable/subscriptions, your help would be greatly appreciated.
Thank you.