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

5

我创建了一个函数,基本上是循环遍历数组并创建文件。我开始使用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' },
];

我一直在阅读,但无法弄清楚如何使用jest进行测试。没有可供参考的示例。我尝试安装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个回答

7

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

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
    );
  });
});

在这里,您可以了解更多关于自动模拟的内容。


很酷,我有一些可行的测试,并且开始有意义了。我想在添加文件后,在“模拟”文件系统上执行类似于fs.existsSync()的操作是不可能的。你只能检查像上面那样的指标,对吗? - jones
@jones,如果 fs.existsSync() 返回 true,那么你的代码应该执行 X,否则应该执行 Y,这样描述是有意义的。 - Teneff
所以基本上是将 fs.existsSync 放在函数本身而不是测试代码中? - jones

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接