iT邦幫忙

2022 iThome 鐵人賽

DAY 25
0
Modern Web

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

Angular TDD 測試從0到1: Day 25 補充 ng-Select

  • 分享至 

  • xImage
  •  

在結束撰寫單元測試的技巧前,想再分享 ng-select 的測試方法。

開發過程中不難遇到會有 dropdown options 的元件,講者使用第三方 lib 的元件,叫做 ng-select

樣式有這些,有興趣的讀者可以看看。

我們就來看看 spec 還可以怎麼寫

使用 ng-select 元件的 HTML & TS

<ng-select
    id="optionDropdown"
    [items]="options"
    [searchable]="false"
    [clearable]="false"
    [(ngModel)]="option"
    (ngModelChange)="selectOption($event)"
></ng-select>
export class TestingNgSelectComponent {
  title = 'example-angular-app';
  options = [];
  option = "";
  
  public selectOption(val) {}
}

Spec

元件分別使用 query, queryAll 這邊只拿 query 的方式做說明。

首先要先認識 line 36 ,講者用 triggerKeyDownEvent 函式,來發動keydown事件。其中的 triggerEventHandler 是針對查詢到的元素,也就是 debugElement 發動事件。
那麼 spec 各別測試了什麼呢?

(1) 測試 selectOption 選擇項目的動作有沒有取到值,所以從範例來看,一開始會先建立 options 清單,接著偵測元素有沒有更新,然後 spy selectOption,再取得 dropdown element。

準備好後,發動「按下空白鍵」,「往下選擇項目」,「按下 Enter」,最後預期 option 2 有被選取到。這樣的順序看起來有點抽象,讀者們可以到 這邊,實際跟著操作看看就大概知道了。

(2) 測試項目的值有沒有被更新,前面的配置一樣,最後預期元件的 option 會等於 option 2

  describe('query', () => {
    it('should call the function selectOption when the user selects a new value from the dropdown', () => {
      //Assign
      component.options = ['option 1','option 2','option 3'];
      component.option = 'option 1';
      componentFixture.detectChanges();
      const spy = spyOn(component, 'selectOption');
      const element = componentFixture.debugElement.query(By.css('#optionDropdown'));
  
      //Act
      triggerKeyDownEvent(element, 32); // space to open the dropdown
      triggerKeyDownEvent(element, 40); // down arrow
      triggerKeyDownEvent(element, 13); // enter to select second option and close the dropdown
      
      //Assert
      expect(spy).toHaveBeenCalledWith('option 2');
    });
  
    it('should update the field option when the user selects a new value from the dropdown', () => {
      //Assign
      component.options = ['option 1','option 2','option 3'];
      component.option = 'option 1';
      componentFixture.detectChanges();
      const element = componentFixture.debugElement.query(By.css('#optionDropdown'));
      
      //Act
      triggerKeyDownEvent(element, 32); // space to open the dropdown
      triggerKeyDownEvent(element, 40); // down arrow
      triggerKeyDownEvent(element, 13); // enter to select second option and close the dropdown
  
      //Assert
      expect(component.option).toEqual('option 2');
    });
  })

  function triggerKeyDownEvent(element: DebugElement, which: number, key = ''): void {
    element.triggerEventHandler('keydown', {
        which: which,
        key: key,
        preventDefault: () => { },
    });
  }

今日心得

測試真的是很值得被開發的領域,雖然一開始並不被關注,但是深入瞭解後會發現小細節的地方,用UT就能先測到,不用等到整合測試才發現。


上一篇
Angular TDD 測試從0到1: Day 24 Tips For Writing Unit Tests
下一篇
Angular TDD 測試從0到1: Day 26 筆記回顧 Refelction (1)
系列文
Angular TDD (Test-driven development ) 從0到130
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言