Node.js 基礎測試

(KJH) Kuan-Jung, Huang
5 min readApr 28, 2019

--

前言

單元測試在軟體品管中佔有舉足輕重的地位,例如我們在開發時可能會先寫測試碼,重構時寫測試碼確保更改不會壞掉,程式碼審查時從執行單元測試開始等等,這篇文章將會探討 Javascript 的測試方式。

測試的程式內容

假設我們寫了以下的一些公用函式,但是我們該如何測試這些函式的回傳值或是狀態改變是否正確?

我將在下篇文章探討 spy ,stub 等測試方式,本篇先說明如何進行一般的回傳值測試。

一般函式測試方式

首先我們撰寫第一個簡單的測試案例: 1 + 2 是否為 3

在圖片的執行結果,顯示的方式是正確的,但如果我們把 `expect(func.add(1,2)).to.equal(3);` 裡面的 3 改為 4,重新執行一次測試,則會顯示下面的結果:

終端機會告訴你本來預期執行結果是 4,但答案是 3,所以出錯外,最下面有顯示

tests\try.test.js:8:34

指的是該測試檔第 8 行有錯,這樣讓工程師方便去檢視是測試案例寫錯還是程式邏輯寫錯。

Callback 函式的測試方式

接著我們要測試 callback function 回傳的結果是不是符合我們的預期。

大家可能注意到這次第 11 行的 it 敘述中的 callback function 加入了 done 的參數,原因是,我們的 usedCallbackAdd 中是一個非同步的函式,他會因為等 0.5 秒才執行 return callback(null, a + b); 延遲得到運算的結果,那為了讓測試的程式知道這個程式要等待回應,透過 done(); 的呼叫讓程式結束。

如果我們不加 done 參數以及不在 expect 述句後面加入 done(); 則會顯示下面的錯誤訊息:

mocha 會很貼心的提醒你,因為超過執行期限了,確保你該測式案例的 async function 在執行完後有使用 done()。

Promise 的兩種測試方式

接著我們要測試 promise function 回傳的結果是不是符合我們的預期。

這樣的寫法雖然測試的結果是對的,但是我們沒有做錯誤處理(做 catch),那我們要如何進行錯誤處裡呢?那就是在 then function 後面做 catch。

為了模擬出 error,我們將第 14 行的註解打開,並註解第 15 行來模擬錯誤。

然後我們可能認為程式應該要這樣寫

因為我們會回傳 fake 字串,所以我們認為 err 應該要等於 fake,但是:

你的終端機可能會出現這樣的錯誤。原因是 fake 是一個 Error 物件,並不是一個字串,所以那樣寫,首先你會看到這樣的錯誤訊息

UnhandledPromiseRejectionWarning: AssertionError: expected [Error: fake] to equal ‘fake'

經過查詢,應該要用

expect(err).to.throw;

如同下面的 gist 這樣

我們透過 error handle 方法來處理 error ,才會正確地處理。

除了使用 then catch 的函式處理 Promise,也使用 async await 來處理 Promise function 的測試。需要注意的地方是,因為你已經在這個 callback function 裡面定義是一個非同步函示了,所以在這邊就不需要使用到 done() 函式,所以不要把 done 參數傳入函式中。

第二種方法是使用 chai-as-promised 這個套件,我們在宣告中加入

const chaiAsPromised = require("chai-as-promised");chai.use(chaiAsPromised);

使用 chai-as-promised 的好處是我們可以在一個 it 述句中同時利用這個套件做多個測試

結語

本篇文章探討在 Mocha 框架底下進行基本的測試回傳值的方法,但是真實世界所撰寫的測試碼遠比這些要複雜得多,後續的文章會持續探討如何做更複雜的單元測試。

完整測試碼如下:

--

--

(KJH) Kuan-Jung, Huang
(KJH) Kuan-Jung, Huang

Written by (KJH) Kuan-Jung, Huang

CTO at Metablox.co, Founder of AI Users Community in Taiwan

Responses (1)