Search code examples
angularunit-testingkarma-jasminengrx-effects

@ngrx/effects: testing an effect returns empty()


I am using @ngrx/effects 4.1.1. I have an effect that returns an empty observable like this:

@Effect() showDialog$: Observable<Action> = this
.actions$
.ofType( ActionTypes.DIALOG_SHOW )
.map( ( action: DialogAction ) => action.payload )
.switchMap( payload => {
    this.dialogsService.showDialog( payload.className );
    return empty();
} );

I am trying to write a unit test following these guidelines that will test that the effect yields an empty observable. I have this:

describe( 'DialogEffects', () => {
    let effects: DialogEffects;
    let actions: Observable<any>;
    const mockDialogService = {
        showDialog: sinon.stub()
    };

    beforeEach( () => {
        TestBed.configureTestingModule( {
            providers: [
                DialogEffects, provideMockActions( () => actions ),
                {
                    provide: DialogsService,
                    useValue: mockDialogService
                }
            ]
        } );

        effects = TestBed.get( DialogEffects );
    } );

    describe( 'showDialog$', () => {
        it( 'should return an empty observable', () => {
            const dialogName = 'testDialog';
            const action = showDialog( dialogName );

            actions = hot( '--a-', { a: action } );
            const expected = cold( '|' );

            expect( effects.showDialog$ ).toBeObservable( expected );
        } );
    } );
} );

However, Karma (v1.7.1) complains:

Expected [ ] to equal [ Object({ frame: 0, notification: Notification({ kind: 'C', value: undefined, error: undefined, hasValue: false }) }) ].

How do I test that the effect returns empty()? I have tried modifying the effect metadata using dispatch: false, but this has no effect.

Ideas?


Solution

  • The problem is that you are comparing the actual result against cold('|').

    The pipe character in cold('|') represents the completion of the observable stream. However, your effect will not complete. The empty() observable does complete, but returning empty() from switchMap just sees that observable merged into the effect observable's stream - it does not complete the effect observable.

    Instead, you should compare the actual result against cold('') - an observable that emits no values and does not complete.