[Cli Todo]单元测试
前言
折磨一下这个命令行小工具,这里使用的是jest,主要的测试内容是文件的读写能力
测试流程
- 
创建__tests__/db.spec.js
 
- 
明确目标,我们需要测试fs的读写,因此要进行mock
 
- 
创建__mocks__/fs.js
 
- 
写测试代码 
- 
运行测试  
 
- 
大功告成 
代码分析
通过jest.mock()对fs进行mock
| 12
 3
 4
 
 | 
 const fs = require('fs')
 jest.mock('fs')
 
 | 
这里使用了describe来测试
| 12
 3
 4
 5
 6
 7
 
 | 
 describe('db', () => {
 it('can read', () => {})
 it('can write', () => {})
 })
 
 
 | 
由于使用到了fake fs,因此我们要准备好假身的功能
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 
 | 
 
 const fs = jest.createMockFromModule('fs')
 const _fs = jest.requireActual('fs')
 
 Object.assign(fs, _fs)
 
 
 let readMocks = {}
 
 fs.setReadFileMock = (path, error, data) => {
 readMocks[path] = [error, data]
 }
 
 fs.readFile = (path, options, callback) => {
 
 if (callback === undefined) callback = options
 if (path in readMocks) {
 callback(...readMocks[path])
 } else {
 _fs.readFile(path, options, callback)
 }
 }
 
 
 let writeMocks = {}
 
 fs.setWriteFileMock = (path, fn) => {
 writeMocks[path] = fn
 }
 
 fs.writeFile = (path, data, options, callback) => {
 if (path in writeMocks) {
 writeMocks[path](path, data, options, callback)
 } else {
 _fs.writeFile(path, data, options, callback)
 }
 }
 
 
 | 
假身准备完毕,开始写测试的主体
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 
 | 
 describe('db', () => {
 it('can read', async () => {
 const data = [{title: 'hi', done: true}]
 fs.setReadFileMock('/testRead', null, JSON.stringify(data))
 const list = await db.read('/testRead')
 expect(list).toStrictEqual(data)
 })
 it('can write', async () => {
 let fakeFile = ''
 fs.setWriteFileMock('/testWrite', (path, data, callback) => {
 fakeFile = data
 callback(null)
 })
 const list = [{title: "test1", done: true}, {title: "test2", done: false}]
 await db.write(list, '/testWrite')
 expect(fakeFile).toBe((JSON.stringify(list) + '\n'))
 })
 })
 
 
 | 
为了保障每条测试项都互不干扰,我们需要做一个clear的操作
| 12
 3
 4
 5
 6
 
 | 
 fs.clearMocks = () => {
 readMocks = {}
 writeMocks = {}
 }
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 
 | 
 describe('db', () => {
 afterEach(() => {
 fs.clearMocks()
 })
 ...
 })
 
 | 
至此测试代码全部写完了。
后记
这是一个简单的单元测试,如果你有意见或建议,欢迎留言告诉我~