2017-10-06 2 views
0

J'ai un service simple dans mon application comme si ...Test d'un service simple qui utilise .next, dans .subscribe angulaire 4 en utilisant Karma/Jasmin

import {Injectable} from '@angular/core'; 
import {Observable} from 'rxjs/Observable'; 
import {Subject} from 'rxjs/Subject'; 

@Injectable() 
export class WizardDialogNavigationService { 

    public navAction$: Observable<any>; 
    private navActionSubject: Subject<any> = new Subject(); 

    constructor() { 
    this.navAction$ = this.navActionSubject.asObservable(); 
    } 

    public navAction(action: string): void { 
    this.navActionSubject.next(action); 
    } 
} 

Ce n'est pas le service le plus complexe, juste me permet de communiquer entre les composants. Maintenant j'ai besoin de le tester, je dois admettre que je connais très peu les tests. Je veux juste vérifier que, lorsque WizardDialogNavigationService.navAction est appelé le navAction$ Observable contient la chaîne passée, donc j'écrit ce qui suit ...

import {TestBed, inject, async} from '@angular/core/testing'; 
import {Observable} from 'rxjs/Rx'; 
import {expect} from 'chai'; 
import * as sinon from 'sinon'; 
import {WizardDialogNavigationService} from './wizard-dialog-navigation.service'; 

describe('WizardDialogNavigationService',() => { 
    beforeEach(() => { 
    TestBed.configureTestingModule({ 
     providers: [WizardDialogNavigationService] 
    }); 
    }) 

    describe('navAction$ Observable',() => { 

    let sut: WizardDialogNavigationService; // sut = Service Under Test 

    beforeEach(inject([WizardDialogNavigationService], (service: WizardDialogNavigationService) => { 
     sut = service; 
    })); 

    it('should be the last passed value', async(() => { 
     const resultList = []; 
     sut.navAction('TestString'); 

     sut.navAction$.subscribe((result) => resultList.push(result)); 
     console.log(resultList); // output is [] 
     expect(resultList.indexOf('TestString')).to.equal(0); 
    })); 
    }); 
}); 

Je pense que je vais sur ce mal que le tableau ne contient pas de résultats de la valeur passée? C'est comme si le .next() .subscribe() n'était pas appelé/couru. Si quelqu'un peut me dire où je me trompe, je l'apprécierais.

+0

Le 'Observable' n'exécutera pas la' subscribe'with la dernière valeur, car il est chaud. Avez-vous essayé de vous abonner au «sujet» lui-même? – Dinistro

+0

Je l'ai essayé aussi en créant le public 'navActionSubject', puis en m'inscrivant dans le test' sut.navActionSubject.subscribe ((result) => console.log (result)); 'ceci n'a pas de sortie non plus ... –

Répondre

1

Vous avez besoin d'un BehaviorSubject qui va retourner la valeur déjà stockée, si vous lui subscribe directement.

Ainsi vous pouvez changer le Subject en un BehaviorSubject et vous y abonner et cela fonctionnera.

Doc:

https://github.com/ReactiveX/rxjs/blob/master/doc/subject.md#behaviorsubject

+0

Vous voulez dire dans mon code de composant, quelque chose comme ceci 'public navActionSubject: BehaviorSubject = nouveau BehaviorSubject (null);' –

+0

@Mark Sandman excactly – Dinistro

+0

Brillant - bonne réponse - merci! –