2017-10-12 6 views
-1

Je souhaite simuler un service que j'ai construit dans mon application angulaire. Mon service est ci-dessous:Se moquer d'un service angulaire qui a RxJS Observables pour les tests

@Injectable() 
export class WizardDialogNavigationService { 

    public navAction$: Observable<any>; 
    public navActionSubject: BehaviorSubject<any> = new BehaviorSubject(null); 

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

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

J'utiliser dans un composant où je l'injectent dans mon constructeur, puis l'ajouter à un abonnement dans la méthode OnInit, par exemple (code du composant) - mon code est ci-dessous, avis J'ajoute seulement ce qui est pertinent.

private navSubscription: Subscription = new Subscription(); 

constructor(private wizardDialogNavigationService: WizardDialogNavigationService) {} 

public ngOnInit(): void { 
     this.navSubscription.add(this.wizardDialogNavigationService.navAction$.subscribe((direction) => { 
     this.moveMaterialStepper(direction); 
    })); 
    } 

J'ai besoin de Mock mon service pour tester mon élément, mais je vais contourner ce de la mauvaise façon, par exemple, je crée le service maquette comme si ...

class MockWizardDialogNavigationService { 

public navAction$: Observable<any>; 
public navActionSubject: BehaviorSubject<any> = new BehaviorSubject(null); 
// this is wrong? 
constructor() { 
    this.navAction$ = this.navActionSubject.asObservable(); 
    } 

    public navAction(action: string): void { 
    // how do I mock a .next? 
    } 
} 

La classe est en haut de mon dossier de test (de spec.ts), je puis ajouter dans les fournisseurs objet

{provide: WizardDialogNavigationService, useValue: MockWizardDialogNavigationService}, 

et plus tard ajouter un bout que je peux écouter quand la méthode navAction est appelée:

stubWizardService = sinon.createStubInstance(WizardDialogNavigationService); 

Cependant, je pense que cela est faux, je suis usure que je déclare la navAction $ observable dans la simulation et lors de l'exécution de mes tests, je reçois l'erreur suivante:

Uncaught (in promise): TypeError: undefined is not an object (evaluating 'this.wizardDialogNavigationService.navAction$.subscribe')

Quelqu'un pourrait-il expliquer peut-être ce que je besoin de faire pour se moquer du service et prévenir l'erreur? Si je ne me suis pas bien expliqué ou si plus de code est requis, faites le moi savoir. Je connais très peu les tests et j'essaie d'apprendre.

+1

En posant la même question [encore une fois] (https://stackoverflow.com/q/46688100/3001761) et [encore] (https://stackoverflow.com/q/46689914/3001761) et en le supprimant n'est pas susceptible de vous obtenir une réponse. Les docs Angular incluent un exemple de test des composants qui reposent sur les services asynchrones: https://angular.io/guide/testing#test-a-component-with-an-async-service – jonrsharpe

+0

Il suffit de lire le guide puis .... – Swoox

Répondre

0

Il est important de se moquer à la fois du service et de l'appel de service. Vous ne voulez pas utiliser la vraie promesse parce qu'elle traite d'async et peut échouer. Vous pouvez vous moquer des erreurs.

Ceci est un exemple de comment vous pouvez vous moquer de votre service.

it('should mock videos', inject([VideoService], (videoService: VideoService) => { 
     videos = [ 
      { id: 0, name: 'Superman' }, 
      { id: 1, name: 'Superman part 2' } 
      ] 
     spyOn(videoService, 'videos').and.returnValue(videos); 
     fixture.detectChanges(); 
     expect(component.getVideoOne()).toContain(Superman); 

     }); 
0

Après les conseils de @jonsharpe je trouve que le problème - j'ai enlevé la classe de service Mock et créé une instance de souche comme si

MockWizardDialogNavigationService = sinon.createStubInstance(WizardDialogNavigationService); 

je gardais le service dans le tableau des fournisseurs

{provide: WizardDialogNavigationService, useValue: MockWizardDialogNavigationService}, 

alors je déclare la navAction $ comme si

TestBed.compileComponents().then(() => { 
// some code removed 
     stubWizardService.navAction$ = Observable.empty(); 

}); 

tout fonctionne!