Jest 外部依賴 & 模擬
-
在 Jest 測試框架中,不具備網頁環境。
-
對於測試需要用到的 Library ,需要用引入模組的方式使測試能夠正常運作。
-
而若需要對網頁做 DOM manipulation ,需要用模擬的方式創建 DOM 環境。
─ 引入模組
-
若是環境相關的引用可以另外寫一隻 setupTests.js 在裡面做全域宣告(global.)的方式,並在上一篇 Jest Testing - Introduction 中提到的 package.json 裡設定,能夠在執行每個測試檔案前先執行 setupTests.js 做 initial。
- Jest 測試框架,需要使用的模組需要透過 npm 安裝
- 例如:jquery、kendo-ui、i18next
- 例如:jquery、kendo-ui、i18next
- jquery
- Jest 使用 Node.js,而在 Node.js 中並沒有內建的 ﹩ 符號,它不會自動將 ﹩ 視為 jQuery。所以,為了在 Jest 測試中使用 ﹩ 符號來調用 jQuery 函數,你需要將 ﹩ 指派給 jQuery。
// setupTests.js // 載入 jQuery 並指派 $ 使用 jquery 模組引用 const jquery = require('jquery'); global.jQuery = jquery; global.$ = jquery;
- kendo-ui
- 要在 Jest 測試中使用 Kendo UI 提供的相關功能進行測試,需要引用 @progress/kendo-ui,而在 kendo 模組用會用到 TextEncoder 與 TextDecoder,所以也要引入。
// setupTests.js global.TextEncoder = require('util').TextEncoder; global.TextDecoder = require('util').TextDecoder; global.kendo = require('@progress/kendo-ui');
- i18next
- 將 i18next 函數引用並全域宣告
// setupTests.js const i18next = require('i18next'); global.i18next = i18next;
─ 引入外部依賴
- 使用 require 引入模組
-
require 是 Node.js 中常見的引入模組的方式。
-
要將 JavaScript 檔案變成一個模組,需要將其中的功能進行封裝,然後透過 module.exports 將這些功能暴露給其他程式碼。
-
這樣其他程式碼就可以通過 require 或 import 的方式引入你的模組並使用其中的功能。
-
以下舉例,定義了一個函數 myFunction,並使用 module.exports 將這個函數暴露出來。
// Module.js function TestFunction() { console.log('This is TestFunction'); } module.exports = { TestFunction: TestFunction };
-
可以在測試的檔案中引入 Module.js 並使用 TestFunction。
// Module.test.js const Module = require('./Module'); Module.TestFunction(); // 調用 TestFunction 函數
-
或是在 setupTests.js 進入點全域載入。
// setupTests.js global.Module = require('./Module'); // Module.test.js Module.TestFunction(); // 調用 TestFunction 函數
-
而要讓測試檔案可以正確找到模組,需要在 package.json 文件中添加 moduleDirectories 設置,模組放置的路徑。
"jest": { "moduleDirectories": [ "../path/folder" ] },
-
- 或是使用 fs.readFileSync 與 eval 讀取並執行檔案 (這個方式無法追蹤覆蓋率)。
-
不包成模組可以用 Node.js 的 fs 模組來讀取指定路徑的 JavaScript,並使用 eval 函數將其執行。
// setupTests.js const path = require('path'); const fs = require('fs'); global.Module = fs.readFileSync(path.resolve(__dirname, '../path/folder/Module.js'), 'utf-8'); eval(global.Module);
-
─ 模擬 DOM 環境
-
Jest 使用 Node.js 環境來執行測試,在測試運行時沒有真正的 DOM 環境可供測試 DOM 相關的程式碼。
-
將 “testEnvironment”: “jest-environment-jsdom” 添加到 package.json 配置中,Jest 將會使用 JSDOM 來模擬一個瀏覽器環境。
-
jest-environment-jsdom 提供了一個基於 jsdom 的模擬 DOM 環境,用於在 Node.js 中模擬瀏覽器環境進行測試。可以在執行測試時訪問 DOM 元素、執行 DOM 操作以及測試與 DOM 相關的程式碼,而無需實際打開瀏覽器。
"jest": { "testEnvironment": "jest-environment-jsdom" },
-
-
引入 jsdom ,並 mock 環境以便使用 DOM API。
// setupTests.js const jsdom = require('jsdom'); const { JSDOM } = jsdom; // 模擬 DOM 環境 const dom = new JSDOM('<!doctype html><html><body></body></html>'); global.window = dom.window; global.document = dom.window.document; global.navigator = dom.window.navigator; global.HTMLElement = dom.window.HTMLElement || class {};
─ 模擬 window
-
在前端測試中有些方法會用到 window 方法,這邊利用 Jest 提供的 jest.fn(),建立 window 的模擬方法。
-
例如設置 global.window.close 為一個模擬函式,當在測試中呼叫 window.close() 時,實際上是呼叫了這個模擬函式。
// setupTests.js global.window.close = jest.fn(); global.window.alert = jest.fn(); global.window.confirm = jest.fn(); Object.defineProperty(window, 'location', { value: { href: 'http://example.com' }, writable: true, });
-