2017-10-12 56 views
-1

我希望模擬我在Angular App中構建的服務。我的服務是如下:嘲諷有RxJS Observables測試的角度服務

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

我在我把它注射到我的構造函數,然後將其添加到在OnInit方法的訂閱,例如(組件代碼)的組件使用此 - 我的代碼如下,通知我只添加相關的內容。

private navSubscription: Subscription = new Subscription(); 

constructor(private wizardDialogNavigationService: WizardDialogNavigationService) {} 

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

我需要模擬我的服務來測試我的組件,但是我解決這個走錯了路,比如,我創建模擬服務是這樣的...

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? 
    } 
} 

類在我的測試文件(spec.ts)的頂部,我然後將其添加在供應商對象

{provide: WizardDialogNavigationService, useValue: MockWizardDialogNavigationService}, 

,並在以後添加存根,以便我可以監聽當navAction方法被稱爲:

stubWizardService = sinon.createStubInstance(WizardDialogNavigationService); 

不過,我覺得這是不對的,我烏蘇雷我如何申報navAction $觀察到了模擬和運行我的測試時,我得到了以下錯誤:

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

可能有人或許可以解釋什麼,我需要做模擬服務並防止錯誤?如果我沒有解釋好自己,或者需要更多的代碼,請告訴我。我對測試知之甚少,我正在努力學習。

+1

再次詢問[同樣的問題](https://stackoverflow.com/q/46688100/3001761)和[再次](https://stackoverflow.com/q/46689914/3001761)並刪除它不是很可能會給你一個答案。 Angular文檔包含一個測試依賴異步服務的組件示例:https://angular.io/guide/testing#test-a-component-with-an-async-service – jonrsharpe

+0

只需閱讀指南,然後.... – Swoox

回答

0

這是模擬服務和服務調用的導入。您不想使用真正的承諾,因爲它處理異步並可能失敗。你可以嘲笑錯誤。

這是一個例子,你可以嘲笑你的服務。

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

@jonsharpe的意見後,我發現了問題 - 我刪除了模擬服務類和創建像這樣

MockWizardDialogNavigationService = sinon.createStubInstance(WizardDialogNavigationService); 

存根比如我不停地提供一個存儲在服務

{provide: WizardDialogNavigationService, useValue: MockWizardDialogNavigationService}, 

然後我聲明navAction $就這樣

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

}); 

一切正常!