memfs icon indicating copy to clipboard operation
memfs copied to clipboard

How to replace mockFs in mocha

Open dicolasi opened this issue 1 year ago • 0 comments

Hi all, I am in the process of replacing mock-fs with mem-fs due to its lack of support for node 20.X. I am struggling to get mem-fs working in this simple case:

Here the original test case with mock-fs:

  it('should use local hosts if they exist', async () => {
    mockFs({
      'admin/exchange-hosts.yaml': mockFs.load('test/unit/input-files/exchange-hosts.yaml'),
      'exchange-config': mockFs.load('test/unit/input-files/gateway/exchange-config-integration')
    });
    await validateHostsByEnvironment({ exchangeConfigPath: 'exchange-config', env: Environment.production, validation });
    expect(validation.errors).to.be.empty;
    expect(validation.warnings).to.be.empty;
    expect(validation.info).to.contain('[prod/real.yaml] Hosts authorised');
    expect(getExchangeHostsRawStub.notCalled).to.be.true;
  });

and here the refactored one with mem-fs that does not work:

  it('should use local hosts if they exist', async () => {
    vol.fromNestedJSON({
      'admin/exchange-hosts.yaml': ufs.readFileSync('test/unit/input-files/exchange-hosts.yaml'),
      'exchange-config': await loadIntoMockFS('test/unit/input-files/gateway/exchange-config-integration'),
    }, appPath);
    await validateHostsByEnvironment({ exchangeConfigPath: 'exchange-config', env: Environment.production, validation });
    expect(validation.errors).to.be.empty;
    expect(validation.warnings).to.be.empty;
    expect(validation.info).to.contain('[prod/real.yaml] Hosts authorised');
    expect(getExchangeHostsRawStub.notCalled).to.be.true;
  });

the method loadIntoMockFS is here:

async function loadIntoMockFS(dirPath: string): Promise<NestedDirectoryJSON> {
  const entries = await fsPromises.readdir(dirPath, {withFileTypes: true});
  const fileTree: NestedDirectoryJSON = {};

  for (const entry of entries) {
    const entryPath = path.join(dirPath, entry.name);
    if (entry.isDirectory()) {
      fileTree[entry.name] = await loadIntoMockFS(entryPath);
    } else if (entry.isFile()) {
      fileTree[entry.name] = await fsPromises.readFile(entryPath, 'utf-8');
    }
  }

  return fileTree;
}

I am not sure I actually need the loadIntoMockFS method at all. The test fail since it cannot find the folde exchange-config cannot be found (but if I print vol.tree I can definitely see it).

I am sure I am missing something stupid here :) For instance, I would need to stub the fs, fs-extra in the src code, but I do not know an elegant way to achieve that using sinon.

Can anyone please help?

dicolasi avatar Apr 16 '24 16:04 dicolasi