全端網站設計範例:後端單元測試

本篇為「全端網站架構」中的後端範例及細節。接續上一篇:全端網站設計範例:後端登入驗證機制

此專案的單元測試將會使用 Jest 這個框架來實做。

安裝 Jest 相關套件

1
$ yarn add -D jest @types/jest ts-jest

其中 ts-jest 為 jest 在 TypeScript 的預處理套件。

新增 Jest 設定檔

在後端根目錄下新增 jest.config.js

1
2
3
4
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
};

(以下待整理)

1
2
3
4
5
6
7
8
9
10
11
const { pathsToModuleNameMapper } = require('ts-jest/utils');
const { compilerOptions } = require('./tsconfig.json');

module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',

// Map paths from tsconfig
modulePaths: [compilerOptions.baseUrl],
moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths),
};

Refs - https://medium.com/@fmoessle/typescript-paths-with-ts-node-ts-node-dev-and-jest-671deacf6428


Hello World 單元測試

在後端根目錄下新增 hello.test.ts 的檔案,用以測試。

1
2
3
4
5
describe('First test', () => {
it('Hello World', () => {
expect(1).toBe(1);
});
});

然後下指令 npx jest,就會由 Jest 自動執行含 .test. 檔名的測試檔。成功的話會輸出類似以下的結果。

1
2
3
4
5
6
7
8
 PASS  test/hello.test.ts
First test
✓ Hello World (2 ms)

Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 2.462 s

如此一來便可以用 Jest 來進行測試,測試的程式碼也能用 TypeScript 來撰寫。

Import 要做測試的單元

Hello World 完畢之後,我們便來測試看看實際的 Function。由於單元測試的目的就是檢查某個最小的元件有沒有問題,並求覆蓋越多這種元件越好,因此每個要測試的元件應該得和其它元件是相互獨立的。

通常來說就是一個 Function,而且給定特定的 Input,應該要能夠輸出一樣,或有規律的 Output,不應該有 Side Effects。假設我們要做一個這樣的 Function,如果此 Function 裡面呼叫 Database 的 Query,不可控的變數就多了,不適合將這個 Function 的測試稱做 Unit Test。

那麼就先來做一個可以測試的單元吧。

src/ 底下新增一個資料夾 lib,裡面再新增一個檔案 greet.ts,我們來做一個簡單的回傳問候文字 Function。

1
2
3
4
5
const getGreetText = (name: string): string => `Hello ${name}`;

export default {
getGreetText,
};

就這麼簡單,傳入一個 name 為 Input,輸出 Hello 加上名字。

撰寫測試

我們修改剛剛的 hello.test.ts,將其內容改成

1
2
3
4
5
6
7
import greet from '../src/lib/greet';

describe('First Test', () => {
it('Get greeting text', async () => {
expect(greet.getGreetText('John')).toBe('Hello Worng');
});
});

執行 npx jest 後應該可以發現 Jest 所回傳給你的錯誤

1
2
Expected: "Hello Worng"
Received: "Hello John"

沒錯,這個測試的開頭我們故意把期望的結果打錯,目的是確認這個測試是有效果的,不然在某些被我們忽略的情況下,這個測試搞不好會通過。

我們將期望的字串改回 Hello John,再跑一次測試應該就能通過了!

參考資料

  1. Medium - Testing with Jest in TypeScript and Node.js for Beginners