React 16 Jest手动模拟(Manual Mocks)
2019獨角獸企業重金招聘Python工程師標準>>>
轉載地址
React 16 Jest手動模擬(Manual Mocks)
項目初始化
git clone https://github.com/durban89/webpack4-react16-reactrouter-demo.git? cd webpack4-react16-reactrouter-demo git fetch origin git checkout v_1.0.27 npm install?
手動模擬(Manual Mocks)
手動模擬主要功能是用于存儲模擬的數據。
例如,我可能希望創建一個允許您使用虛假數據的手動模擬,而不是訪問網站或數據庫等遠程資源。
這可以確保您的測試快速且不易碎(not flaky)。
?
模擬水果模塊(Mocking fruit?modules)
通過在緊鄰模塊的__mocks__/子目錄中編寫模塊來定義手動模擬。這個方式我在前面文章中的實例中也有用到過,具體的可以參考之前的文章,這里我說下大概的流程
例如,要在src/lib目錄中模擬一個名為fruit的模塊,則分別創建文件src/lib/fruit.js和文件src/lib/__mocks__/fruit.js的文件。
請注意__mocks__文件夾區分大小寫。如果命名目錄是__MOCKS__,則可能在某些系統上測試的時候會中斷。
注意點
當我們在測試中需要該模塊時,還需要顯式的調用jest.mock('./moduleName')。
模擬Node核心模塊(Mocking Node modules)
如果正在模擬的模塊是Node module(例如:lodash),則模擬應放在與node_modules相鄰的__mocks__目錄中(除非您將根配置為指向項目根目錄以外的文件夾)并將自動模擬。
沒有必要顯式調用jest.mock('module_name')。
可以通過在與范圍模塊的名稱匹配的目錄結構中創建文件來模擬范圍模塊。
例如,要模擬名為@scope/project-name的作用域模塊,請在__mocks__/@scope/project-name.js創建一個文件,相應地創建@scope/目錄。
注意點
如果我們想模擬Node的核心模塊(例如:fs或path),那么明確地調用。
例如:jest.mock('path')是必需的,因為默認情況下不會模擬核心Node模塊。
實例演示
當給定模塊存在手動模擬時,Jest的模塊系統將在顯式調用jest.mock('moduleName')時使用該模塊。
但是,當automock設置為true時,即使未調用jest.mock('moduleName'),也將使用手動模擬實現而不是自動創建的模擬。
要選擇不使用此行為,您需要在應使用實際模塊實現的測試中顯式調用jest.unmock('moduleName')。
?
注意點
為了正確模擬,Jest需要jest.mock('moduleName')與require/import語句在同一范圍內。
?
假設我們有一個模塊,它提供給定目錄中所有文件的摘要。在這種情況下,我們使用核心(內置)fs模塊來演示
?
src/lib/FileSummarizer.js
const fs = require('fs');function summarizeFilesInDirectorySync(directory) {return fs.readdirSync(directory).map(fileName => ({directory,fileName,})); }exports.summarizeFilesInDirectorySync = summarizeFilesInDirectorySync;?
由于我們希望我們的測試避免實際操作磁盤(這非常慢且易碎[fragile]),我們通過擴展自動模擬為fs模塊創建手動模擬。
我們的手動模擬將實現我們可以為我們的測試構建的fs API的自定義版本:
src/lib/__mocks__/fs.js
const path = require('path');const fs = jest.genMockFromModule('fs');let mockFiles = Object.create(null);function __setMockFiles(newMockFiles) {mockFiles = Object.create(null);const keys = Object.keys(newMockFiles);for (let index = 0; index < keys.length; index += 1) {const file = keys[index];const dir = path.dirname(file);if (!mockFiles[dir]) {mockFiles[dir] = [];}mockFiles[dir].push(path.basename(file));} }function readdirSync(directoryPath) {return mockFiles[directoryPath] || []; }fs.__setMockFiles = __setMockFiles; fs.readdirSync = readdirSync;module.exports = fs;現在我們編寫測試。
請注意,我們需要明確告訴我們要模擬fs模塊,因為它是一個核心Node模塊:
src/__tests__/FileSummarizer-test.js
const fs = require('fs'); const FileSummarizer = require('../lib/FileSummarizer');jest.mock('fs');describe('listFilesInDirectorySync', () => {const MOCK_FILE_INFO = {'/path/to/file1.js': 'console.log("file1 contents");','/path/to/file2.txt': 'file2 contents',};beforeEach(() => {// Set up some mocked out file info before each testfs.__setMockFiles(MOCK_FILE_INFO);});test('includes all files in the directory in the summary', () => {const fileSummary = FileSummarizer.summarizeFilesInDirectorySync('/path/to');expect(fileSummary.length).toBe(2);}); });此處顯示的示例模擬使用jest.genMockFromModule生成自動模擬,并覆蓋其默認行為。
這是推薦的方法,但完全是可選的。
如果您根本不想使用自動模擬,則只需從模擬文件中導出自己的函數即可。
完全手動模擬的一個缺點是它們是手動的 - 這意味著你必須在它們模擬的模塊發生變化時手動更新它們。
因此,最好在滿足您的需求時使用或擴展自動模擬。
為了確保手動模擬及其實際實現保持同步,在手動模擬中使用require.requireActual(moduleName)并在導出之前使用模擬函數修改它可能是有用的。
?
項目實踐地址
https://github.com/durban89/webpack4-react16-reactrouter-demo.git tag:v_1.0.28轉載于:https://my.oschina.net/zhangdapeng89/blog/1845544
總結
以上是生活随笔為你收集整理的React 16 Jest手动模拟(Manual Mocks)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java面试-Java并发编程(六)——
- 下一篇: Python--发送邮件