# 为Node API写单元测试(Jest Mock)

# Mock

在单元测试里, 涉及到文件读写和网络请求的部分并不会调用真实的API去完成, 而是通过模拟(mock)出一段数据当作真实的结果. 按照惯例, 模拟的API需要放在__mocks__文件夹里, 并且要在离调用API最近的地方:

mock

这里以仿写fs.readFile为例, 主要分为两大步: 首先模拟数据, 然后模拟API.

// fs.js
const fs = jest.genMockFromModule('fs') // mock模块
const _fs = jest.requireActual('fs') // 引用真正的模块
Object.assign(fs, _fs)
const mocks = {}

// 模拟数据
fs.mockData = (path, err, data) => {
  mocks[path] = [err, data]
}

// 模拟readFile函数
fs.readFile = (path, options, callback) => {
  if (callback === undefined) callback = options
  if (mocks[path]) {
    callback(...mocks[path])
  } else {
    _fs.readFile(path, options, callback)
  }
}

module.exports = fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# Test

在这里, 我们可以使用mock api开始测试功能了:

jest.mock('fs')
const fs = require('fs')

describe('db', () => {
  it('should read', async function () {
    fs.mockData('/xxx', null, data)
    const result = await fs.readFile('/xxx')
    expect(result).toStrictEqual(data)
  })
})
1
2
3
4
5
6
7
8
9
10