Jest - 模拟和测试 node.js 文件系统

Posted

技术标签:

【中文标题】Jest - 模拟和测试 node.js 文件系统【英文标题】:Jest - Mocking and testing the node.js filesystem 【发布时间】:2020-02-13 05:48:11 【问题描述】:

我创建了一个函数,它基本上循环数组并创建文件。我开始使用 Jest 进行测试,以提供一些额外的安全性以确保一切正常,但是我在尝试模拟 Node.js 文件系统时遇到了一些问题。

这是我要测试的功能 - function.ts

export function generateFiles(root: string) 
  fs.mkdirSync(path.join(root, '.vscode'));
  files.forEach((file) => 
    fs.writeFileSync(
      path.join(root, file.path, file.name),
      fs.readFileSync(path.join(__dirname, 'files', file.path, file.name), 'utf-8')
    );
  );


const files = [
   name: 'tslint.json', path: '' ,
   name: 'tsconfig.json', path: '' ,
   name: 'extensions.json', path: '.vscode' ,
];

我一直在阅读,但无法真正弄清楚如何用玩笑来测试它。没有例子可以看。我尝试安装mock-fs,这应该是使用 Node.js FS 模块的模拟版本启动和运行的一种简单方法,但老实说,我不知道从哪里开始。这是我第一次尝试做一个简单的测试 - 这会导致错误,说'没有这样的文件或目录' - function.test.ts

import fs from 'fs';
import mockfs from 'mock-fs';

beforeEach(() => 
  mockfs(
    'test.ts': '',
    dir: 
      'settings.json': 'yallo',
    ,
  );
);

test('testing mock', () => 
  const dir = fs.readdirSync('/dir');
  expect(dir).toEqual(['dir']);;
);

afterAll(() => 
  mockfs.restore();
);

谁能指出我正确的方向?

【问题讨论】:

【参考方案1】:

既然你想测试你的实现,你可以试试这个:

import fs from 'fs';
import generateFiles from 'function.ts';

// auto-mock fs
jest.mock('fs');

describe('generateFiles', () => 
  beforeAll(() => 
    // clear any previous calls
    fs.writeFileSync.mockClear();


    // since you're using fs.readFileSync
    // set some retun data to be used in your implementation
    fs.readFileSync.mockReturnValue('X')

    // call your function
    generateFiles('/root/test/path');
  );

  it('should match snapshot of calls', () => 
    expect(fs.writeFileSync.mock.calls).toMatchSnapshot();
  );

  it('should have called 3 times', () => 
    expect(fs.writeFileSync).toHaveBeenCalledTimes(3);
  );

  it('should have called with...', () => 
    expect(fs.writeFileSync).toHaveBeenCalledWith(
      '/root/test/path/tslint.json',
      'X' // <- this is the mock return value from above
    );
  );
);

Here你可以阅读更多关于自动模拟的信息

【讨论】:

酷,我进行了一些工作测试,它开始变得有意义。我想在添加文件后,在文件系统的“模拟”版本上没有办法像 fs.existsSync() 那样做。您只能检查上述指标,对吗? @jones 描述如果fs.existsSync() 返回true,您的代码应该执行X,否则它应该执行Y 是有意义的 所以基本上将 fs.existsSync 放在函数本身而不是测试代码中?

以上是关于Jest - 模拟和测试 node.js 文件系统的主要内容,如果未能解决你的问题,请参考以下文章

如何在 jest node.js 中测试 if else 条件

Node.js:Jest + redis.quit() 但打开句柄警告仍然存在

Node.js events.js: 163 throw er;使用标志 --runInBand 执行 Jest 时

使用 Jest、AudioContext 进行测试和模拟

跨测试重用 Jest 模块模拟

使用 Jest/Typescript 测试 fs 库函数