是否可以为 Node.js fs.readFile() 编写 Jest 单元测试?

Rya*_*yan 7 javascript unit-testing node.js jestjs

我是 Jest 单元测试的新手,想知道 Jest 是否可以用于测试 Node.js 文件系统模块。

\n\n

我目前有一个包含一首短诗的文本文件,viewText 功能控制台将这首诗记录在我的终端上。

\n\n

使用 Jest,我的目标是编写一个测试来检查viewText函数是否确实正常工作。

\n\n
const viewText = () => {\n  fs.readFile('poem.txt', 'utf8', (err, data) => {\n    if (err) throw err;\n    console.log(data);\n  });\n};\n
Run Code Online (Sandbox Code Playgroud)\n\n

对于 Jest,我尝试过:

\n\n
jest.spyOn(global.console, 'log');\n\nconst mockPoem = 'Some say the world will end in fire, Some say in ice. From what I\xe2\x80\x99ve tasted of desire I hold with those who favor fire ... And would suffice.';\n\ndescribe('viewText', () => {\n  const mockReadFile = jest.fn();\n  mockReadFile.mockReturnValue(mockPoem);\n\n  it('prints poem to console', () => {\n    viewText();\n    expect(global.console.log).toHaveBeenCalledWith(mockPoem);\n  });\n});\n
Run Code Online (Sandbox Code Playgroud)\n\n

通过测试,我想做的就是检查我的viewText函数是否通过测试 - 能够查看mockPoem. 我真的很困惑应该如何使用文件系统模块为函数编写单元测试。

\n

sli*_*wp2 9

这是一个UT解决方案:

\n\n

index.ts:

\n\n
import fs from \'fs\';\n\nexport const viewText = () => {\n  fs.readFile(\'poem.txt\', \'utf8\', (err, data) => {\n    if (err) throw err;\n    console.log(data);\n  });\n};\n
Run Code Online (Sandbox Code Playgroud)\n\n

index.spec.ts:

\n\n
import { viewText } from \'./\';\nimport fs from \'fs\';\n\nconst mockPoem =\n  \'Some say the world will end in fire, Some say in ice. From what I\xe2\x80\x99ve tasted of desire I hold with those who favor fire ... And would suffice.\';\n\ndescribe(\'viewText\', () => {\n  afterEach(() => {\n    jest.restoreAllMocks();\n  });\n  test(\'prints poem to console\', done => {\n    const logSpy = jest.spyOn(console, \'log\');\n    let readFileCallback;\n    // @ts-ignore\n    jest.spyOn(fs, \'readFile\').mockImplementation((path, options, callback) => {\n      readFileCallback = callback;\n    });\n\n    viewText();\n    readFileCallback(null, mockPoem);\n    expect(logSpy).toBeCalledWith(mockPoem);\n    expect(fs.readFile).toBeCalledWith(\'poem.txt\', \'utf8\', readFileCallback);\n    done();\n  });\n\n  test(\'should throw error when read file failed\', done => {\n    let readFileCallback;\n    // @ts-ignore\n    jest.spyOn(fs, \'readFile\').mockImplementation((path, options, callback) => {\n      readFileCallback = callback;\n    });\n\n    viewText();\n    const mError = new Error(\'read file failed\');\n    expect(() => readFileCallback(mError, null)).toThrowError(mError);\n    expect(fs.readFile).toBeCalledWith(\'poem.txt\', \'utf8\', readFileCallback);\n    done();\n  });\n});\n
Run Code Online (Sandbox Code Playgroud)\n\n

100%覆盖率的单元测试结果:

\n\n
 PASS  src/stackoverflow/58810079/index.spec.ts (11.118s)\n  viewText\n    \xe2\x9c\x93 prints poem to console (23ms)\n    \xe2\x9c\x93 should throw error when read file failed (3ms)\n\n  console.log node_modules/jest-mock/build/index.js:860\n    Some say the world will end in fire, Some say in ice. From what I\xe2\x80\x99ve tasted of desire I hold with those who favor fire ... And would suffice.\n\n----------|----------|----------|----------|----------|-------------------|\nFile      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |\n----------|----------|----------|----------|----------|-------------------|\nAll files |      100 |      100 |      100 |      100 |                   |\n index.ts |      100 |      100 |      100 |      100 |                   |\n----------|----------|----------|----------|----------|-------------------|\nTest Suites: 1 passed, 1 total\nTests:       2 passed, 2 total\nSnapshots:   0 total\nTime:        13.129s\n
Run Code Online (Sandbox Code Playgroud)\n\n

源代码:https ://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58810079

\n