簡體   English   中英

模擬具有 RxJS Observables 進行測試的 Angular 服務

[英]Mocking an Angular Service that has RxJS Observables for testing

我希望模擬我在我的 Angular 應用程序中構建的服務。 我的服務如下:

@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) 的頂部,然后我將其添加到 providers 對象中

{provide: WizardDialogNavigationService, useValue: MockWizardDialogNavigationService},

然后添加一個存根,以便我可以在調用 navAction 方法時進行監聽:

stubWizardService = sinon.createStubInstance(WizardDialogNavigationService);

但是我覺得這是錯誤的,我很確定如何在模擬中聲明 navAction$ observable 並且在運行我的測試時出現以下錯誤:

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

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

模擬服務和服務調用很重要。 您不想使用真正的承諾,因為它處理異步並且可能會失敗。 你可以模擬錯誤。

這是一個如何模擬服務的示例。

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

      });

在@jonsharpe 的建議之后,我發現了問題 - 我刪除了 Mock Service 類並創建了一個像這樣的存根實例

MockWizardDialogNavigationService = sinon.createStubInstance(WizardDialogNavigationService);

我將服務保存在 providers 數組中

{provide: WizardDialogNavigationService, useValue: MockWizardDialogNavigationService},

然后我像這樣聲明 navAction$

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

}); 

一切正常!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM