博客 / 詳情

返回

Angular單元測試框架裏API toHaveBeenCalledTimes的工作原理

看這樣一段代碼:

 let spiedFirstFocusable = spyOn(
      keyboardFocusService,
      'findFirstFocusable'
    ).and.returnValue(el);
    fixture.detectChanges();

    expect(document.activeElement.id).toEqual('a');
    expect(spiedFirstFocusable).toHaveBeenCalledTimes(ELEMENT_FOCUSED_TIME);

spiedFirstFocusable是spyOn方法針對實例keyboardFocusService的findFirstFocusable方法進行監控後返回的句柄。藉助該句柄,我們可以使用toHaveBeenCalledTimes方法,得到其在單元測試過程中實際調用的次數。

expect方法:基於傳入的spec創建一個expectation. 在我們的例子裏,傳入的spec就是keyboardFocusService.findFirstFocusable被spy之後的版本:

Expectation通過工廠方法創建,該工廠方法接受兩個參數,第一個參數為spied method handle:

第二個參數為單元測試代碼運行的spec信息,即下圖高亮代碼:

Expectation工廠方法的實現細節,我們可以略過:

toHaveBeenCalledTimes的函數體是之前wrapSyncCompare包裹函數返回的一個閉包:

待compare的業務邏輯寫在函數matcherFactory裏:

以後我們可以直接在函數toHaveBeenCalledTimes裏設置斷點調試。

  1. 檢查傳入的actual是否是一個spied後的函數。
  2. 將檢查結果設置成默認值false.
  3. 檢查傳入的期望調用次數的值的數據類型是否是Number

Spied版本的函數調用明細,存儲在CallTracker的calls屬性裏:

這個數組裏包含的監控到的方法調用信息有:

  1. 方法調用的輸入參數
  2. 調用方法的實例對象
  3. 調用方法的返回參數

"get the number of invocations of this spy"的實現方法:calls.length

如果calls.length和傳入的期望值expected相等,説明匹配成功,返回success結果:

更多Jerry的原創文章,盡在:"汪子熙":

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.