iT邦幫忙

2022 iThome 鐵人賽

DAY 17
0
Modern Web

Angular TDD (Test-driven development ) 從0到1系列 第 17

Angular TDD 測試從0到1: Day 17 Typescript Unit Test(3) - Observables, Subscription

  • 分享至 

  • xImage
  •  

不意外的今天依舊測試 typescript,不過有趣的是可以來測試 observable,雖然課程有 async function 由於前幾篇有提過,今天就不再重複。

學習課程名稱如下:

  • Testing Subscriptions And Observables
  • Testing Asynchronous Code

元件的 function 變數

我們來看看,原始元件 typescript 檔案

  1. Subscriptions And Observables 元件,調用 ApiService 的 getData 用 subscribe 取值,將其值傳到另一個函式

  2. ApiService 使用到 Subject 可以從外部訂閱

如何測試 Observable function

接著來看看,對應的 Spec 檔案,configureTestingModule 一樣取代成測試用的元件

  1. Subscriptions And Observables 元件
  beforeEach(waitForAsync(() => {
      configureTestingModule({
          declarations: [
            TestingSubscriptionsAndObservablesComponent
          ],
      }).compileComponents();
  }));

在測試 Spec 第一個案例都是先檢查「元件是否存在」,因為前幾篇實做過這邊就不再贅述。
(1) 使用 spyOn 取得元件服務 handleData,字串需與元件函式同名

(2) 接著使用 BehaviorSubject ,手動 emmit 一個新值 line 4。Subject 可以接受外部訂閱,也可以訂閱其他的 Observable,而 BehaviorSubject 會在每次被外部訂閱時,emmit 目前已收到的最新值。

(3) 繼續準備測資,將 ApiService 注入到測試案例,以便後續的使用,line 5

(4) 利用 asObservable() 將 getDataSubject 轉換成單純 Observable,在將值 emmit 給 returnValue 使用

(5) 因為在一開始 line 6 已經在 ngOnInit 調用 getData 狀態已經改變,所以在呼叫一次 init 重新訂閱 getData 函式

(6) 用 next 手動觸發新值輸出 line 10

(7) 第一個 it 檢查 'handleData' 是否至少被呼叫一次,並且帶著5的參數; 第二個 it 檢查 handleData 拿到的回傳值 5 有沒有和前述設定的測資 3 相同。

  it('should call handleData when recieving new data', () => {
    //Assign
    const spy = spyOn(component,'handleData');
    const getDataSubject = new BehaviorSubject<number>(3);
    const apiService = TestBed.inject(ApiService);
    spyOn(apiService,'getData').and.returnValue(getDataSubject.asObservable());

    //Act
    component.ngOnInit(); // Subscribe again since the function was just changed.
    getDataSubject.next(5); // Emit a new value

    //Assert
    expect(spy).toHaveBeenCalledWith(5);
  });

  it('should set the data when recieving new data', () => {
    //Assign
    const apiService = TestBed.inject(ApiService);
    const subject = new BehaviorSubject<number>(3);
    spyOn(apiService,'getData').and.returnValue(subject.asObservable());

    //Act
    component.ngOnInit(); // Subscribe again
    subject.next(5); // Emit a new value

    //Assert
    expect(component.data).toEqual(5);
  });

今日心得

要用文字翻譯測試程式碼,實在有點抽象,而且對 Rxjs 熟悉度還不夠深,所以在理解測試 Observable 這段又繼續補充知識,不過對於 UT 測試 Observable 有基本的認識。

下一篇要來測試沒看過的 Route 和 Local Storage


上一篇
Angular TDD 測試從0到1: Day 16 Typescript Unit Test(2)
下一篇
Angular TDD 測試從0到1: Day 18 Typescript Unit Test(4) - Navigation, Local Storage
系列文
Angular TDD (Test-driven development ) 從0到130
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言