1

I m trying to test an Angular 2 component with fake dependencies.

In fact, I m building a simple TODO app with Ng2 and Redux, and in one of my component, I have an instance of the redux app store.

I need to mock this object and spy on its subscribe method. This way, I m having one solution that looks like following :

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();
            });
        })));
});

And that should 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);
        });
    }
}

My problem is that the test doesn't pass at all, and the stacktrace isn't as explicit :

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)
    at Gulp.<anonymous> (C:\Project\angular2\kanboard\node_modules\gulp\bin\gulp.js:195:15)
    at emitOne (events.js:77:13)
    at Gulp.emit (events.js:169:7)
    at Gulp.Orchestrator._emitTaskDone (C:\Project\angular2\kanboard\node_modules\gulp\node_modules\orchestrator\index.js:264:8)
    at C:\Project\angular2\kanboard\node_modules\gulp\node_modules\orchestrator\index.js:275:23
    at finish (C:\Project\angular2\kanboard\node_modules\gulp\node_modules\orchestrator\lib\runTask.js:21:8)
    at cb (C:\Project\angular2\kanboard\node_modules\gulp\node_modules\orchestrator\lib\runTask.js:29:3)
    at DestroyableTransform.<anonymous> (C:\Project\angular2\kanboard\tasks\test.js:62:13)
    at emitNone (events.js:72:20)
    at DestroyableTransform.emit (events.js:166:7)
    at finishMaybe (C:\Project\angular2\kanboard\node_modules\remap-istanbul\node_modules\through2\node_modules\readable-stream\lib\_stream_writable.js:475:14)
    at endWritable (C:\Project\angular2\kanboard\node_modules\remap-istanbul\node_modules\through2\node_modules\readable-stream\lib\_stream_writable.js:485:3)
    at DestroyableTransform.Writable.end (C:\Project\angular2\kanboard\node_modules\remap-istanbul\node_modules\through2\node_modules\readable-stream\lib\_stream_writable.js:455:41)
    at DestroyableTransform.onend (C:\Project\angular2\kanboard\node_modules\gulp\node_modules\vinyl-fs\node_modules\through2\node_modules\readable-stream\lib\_stream_readable.js:523:10)
    at DestroyableTransform.g (events.js:260:16)
    at emitNone (events.js:72:20)
    at DestroyableTransform.emit (events.js:166:7)
    at C:\Project\angular2\kanboard\node_modules\gulp\node_modules\vinyl-fs\node_modules\through2\node_modules\readable-stream\lib\_stream_readable.js:965:16
    at nextTickCallbackWith0Args (node.js:420:9)
    at process._tickCallback (node.js:349:13)
Remapping done! View the result in report/remap/html-report
npm ERR! Test failed.  See above for more details.

Any idea why the test is failing ?

Otherwise, I m looking for good practices concerning mocking rxjs observable / subscriptions, if anybody have an idea.

Thanks for your help

1 Answer 1

1

I think that the problem is in your expectation. You could try the following:

expect(component.appStore.subscribe).toHaveBeenCalled();

instead of:

expect(component.appStore).toHaveBeenCalled();
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the anwser. But the problem wasn't here :(
Okay, I fixed the problem. It seems that I made a useValue of my mock class... The mock should be a function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.