iT邦幫忙

2022 iThome 鐵人賽

DAY 11
1
Modern Web

今天我想來在 Angular 應用程式上加上測試保護系列 第 11

Day 11 - 單元測試 - 測試 Angular 元件 - Spy 物件

  • 分享至 

  • xImage
  •  

前言

上一篇說明了三種建立 Spy 物件的方法,透過 Spy 物件的替換可以讓單元測試不用與外部資源相依,進而減少測試程式的準備成本;這一篇會來介紹在 Spy 物件中有哪些比較常用的方法可以使用。

方法回傳結果的指定

除了前一篇所利用的 returnValue 方法決定 Spy 服務方法回傳值之外,Jasmine 也針對不同的情境提供了不同的方法。

  • callThrough() - 當我們希望服務方法能依正式作業的方法執行,但又想要驗證呼叫此方法的參數是否正確時,就可以使用 callThrough() 方法。

    spyOn(shoppingCartService, 'add').and.callThrough()
    
  • callFake(fn) - 當服務方法會依不同的測試情境所傳入的值,而有不一樣的回傳值時候,可以利用 callFake() 方法,利用一方法來判斷與決定回傳值。

    spyOn(shoppingCartService, 'add').and.callFake((product) => {
      ...
    });
    
  • throwError(something) - 此方法則可以讓我們指定服務方法拋出例外錯誤。

    spyOn(shoppingCartService, 'add').and.throwError('error message')
    

Spy 物件的驗證

在驗證的部份,Jasmine 也提供了用來驗證目標程式與 Spy 物件互動的方法。

  • toHaveBeenCalled() - 這個方法用來驗證 Spy 物件的方法是否有被呼叫。

    expect(shoppingCartService.add).toHaveBeenCalled();
    
  • toHaveBeenCalledOnceWith(expected) - 用來驗證 Spy 物件方法是否依指定參數被呼叫一次。

    expect(shoppingCartService.add).toHaveBeenCalledOneWith(new Product({}));
    
  • toHaveBeenCalledWith(expected) - 用來驗證 Spy 物件方法是否依指定參數被呼叫。

    expect(shoppingCartService.add).toHaveBeenCalledWith(new Product({}));
    
  • toHaveBeenCalledTimes(times) - 用來驗證 Spy 物件方法是否有被呼叫的次數

    expect(shoppingCartService.add).toHaveBeenCalledTimes(1);
    

加入購物車動作測試程式重構

接下來來拿先前「加入購作車」動作的測試程式,原本是驗證 ShoppingCartService 服務內記錄的資料是否符合預期;但如果服務的方法是需要透 HttpClient 存取資料庫的時候,就無法使用這樣的驗證方式,而改用驗證元件與服務之間的互動。

it('當將產品 C 新增至購物車時, 購物車服務應記錄 1 筆資料', () => {
  // Arrange
  const shoppingCartService = TestBed.inject(ShoppingCartService);
  spyOn(shoppingCartService, 'add').and.callThrough();

  const product = new Product({ id: 3, name: '產品 C', price: 10 });

  component.product = product;
  fixture.detectChanges();

  // Act
  const button = fixture.debugElement.queryAll(By.css('button'))[1];
  button.nativeElement.click();

  // Assert
  expect(shoppingCartService.add).toHaveBeenCalledWith(product);
});

如上面程式,與先前測試程式有兩個地方不同,首先利用 spyOn 方法針對 ShoppingCartServiceadd() 方法建立 Spy 物件,並讓此方法維持著原本的作業。其次利用 toHaveBeenCallWith() 方法驗證在按下「加入購物車」按鈕時,是否有呼叫到 ShoppingCartServiceadd() 方法,且傳入的參數為 product 變數。

執行測試程式

最後就執行 ng test 來確認測試的結果。

https://ithelp.ithome.com.tw/upload/images/20220926/20109645S9HTfiOJyL.png

接下來

這一篇說明了 Spy 物件的設定與驗證方法,完整的測試程式可以參考 GitHub。接下來,則繼續說明在表單上的驗證方式要如何撰寫。


上一篇
Day 10 - 單元測試 - 測試 Angular 元件 - 建立相依的假服務
下一篇
Day 12 - 單元測試 - 測試 Angular 元件 - 測試表單元件
系列文
今天我想來在 Angular 應用程式上加上測試保護30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言