iT邦幫忙

2022 iThome 鐵人賽

DAY 14
0
Modern Web

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

Angular TDD 測試從0到1: Day 14 如何用 configureTestingModule 設定 Unit Test 環境

  • 分享至 

  • xImage
  •  

延續前一天開發環境設定,今天來到 Section 2 設定單元測試環境,依照下列課綱會學習「如何設定TestBed」、「如何用 mock component 做隔離測試」,筆者會將重點整理到此篇,我們就開始吧!

  • Creating A Test App Using A TestBed
  • Creating Mock Components
  • Creating Mock Services
  • Mocking Imported Components And Services
  • Setting Up Navigation In Your Test App
  • The Spec File
  • Creating Unit Tests

單元測試的目標

檢查應用程式的變化,避免其他元件、服務影響測試,所以要保持測試元件狀態不變。

為了達到「狀態固定」,Neil 的方法是建立「空元件替代真實元件」。
這是什麼意思呢?我們照著步驟做

建立 Mock Components

  1. 建立新 Component
  2. 元件名稱同原本元件名稱, i.e 原始元件稱「PlayComponent」, Mock 元件也用同名字
  3. Selector名稱同原本元件, i.e 原始元件選取器稱「app-play-component」, Mock 也同
  4. 不放入 Typescript
  5. 不放入 HTML
  6. 只保留 Inputs, Outputs
  7. 移除 Inputs 相關執行程式碼

範例

  • 原始元件
  • Mock 元件

要測試的 Real Component 會 mapping testing-utils.ts 裡的 Mock Component,Neil 是將所有 Mock Component 整理到 testing-utils.ts

因為每個元件會對應一個 component.spec.ts ,自然而然會習慣 Mock 的資料會在元件資料夾裡面,但 child.component.spec.ts 裡面是空的,讓筆者以為自己看到了什麼,所以整份看下來一開始會有點不習慣。

接下來認識如何建立摩克服務

建立 Mock Services

  1. 建立新 Service
  2. 命不同的名稱, i.e Real Service名稱是 ApiService, Mock的話是 ApiServiceMock
  3. 不放入 Typescript
  4. 保留欄位和 Functions
  5. 函式回傳固定的值

範例

  • 原始 Service

  • Mock Service(1): 取名ApiServiceMock, AuthorisationServiceMock (line 150, line 151)

  • Mock Service(2): provider放上原始的, 用 useClass 取代成 Mock 用的

服務 ( Service ) 同理,要測試的 Real Service 會 mapping testing-utils.ts 裡的 Mock Service。最後用 useClass 將 Real one 取代成 Mock 用的。

Import 測試用的 Module

在測試的時候,有些測項需要特定模組,所以 Angular 也有提供對應的測試模組,讓我們注入到 TestingModule,還有哪些測試模組可以到官網查詢

HttpClientTestingModule,
RouterTestingModule.withRoutes(routes),

Route Mock 設定

如果要測試登入,就會需要用 Route 設定可以使用的頁面,在 testing-utils.ts 裡也可以將 Mock Route 設定進來。在 RouterTestingModule 使用設定的 Route

testing-utils.ts 如何運作?

上述提到「單元測試的目標」、還有 Mock data 如何建立,這邊來說明 testing-utils.ts 在這專案扮演多大的角色。

  1. Mock 用的 Component Selector 都同名,只是示意用的,要改成對應元件的名稱。
  2. 所有測試 spec 都是 import testing-utils.ts 如: line 2,所以當 line 10 傳入 declarations 某個 component,就能夠直接用 testing-utils.ts 的設定。
  3. 如此一來,只要有 new spec 增加,只要在這份新增 mock data 和加入 dependency,維護一份檔案就好。確保 mock data 和 real component 隔離測試,spec 只針對 預期行為、UI、是否存在、狀態 進行測試。

今日心得

能夠生出這篇,真的要感謝一位 Mentor ,但感謝的話留到最後一天說。

來說說學習心得,這個章節看似簡單,但筆者在這章影片來來回回好幾次,重複看是不是哪裡有誤解,後來和 Mentor 討論 (對答案) 自己的理解,才發現原來,有些真的是為了教學方便的寫法,就像 testing-utils.ts ,會有同名的 Selector ,讓筆者不明白用 mock 取代 real 的意思 (不同元件但同個Selector,是如何取代??),再者,通常 spec 是寫在要測試物件的資料夾,筆者看不懂單獨 spec 和 utils 的關聯,原來是用一份維護 mock 和 dependency。

用一份的缺點是,隨著時間演進這份 utils 會越來越長,放 mock data 的地方要寫註解才方便對應,還有 trace testing 不會太直覺是哪裡有問題,是 spec 還是 testingModule的問題? 好處當然就是只要維護一份。

如果維護各自 spec 的缺點是,mock data 和 testingModule 會重複寫,好處是 trace testing 可以只跑有問題的 spec ,比較好找問題。

但其實兩種都可以,看團隊習慣的開發方式,能夠舒適的與彼此 co-work 最重要。

希望讀到這的你還沒有暈?!

下一篇要開始一系列的 Typescript 測試

參考資料

ng test --include=**/my.component.spec.ts // single file
ng test --include'**/service/*.spec.ts // multiple files inside a folder

上一篇
Angular TDD 測試從0到1: Day 13 建立專案
下一篇
Angular TDD 測試從0到1: Day 15 Typescript Unit Test(1)
系列文
Angular TDD (Test-driven development ) 從0到130
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言