Skip to content

test_runner: add mock file system API - #65798

Open
mcollina wants to merge 1 commit into
nodejs:mainfrom
mcollina:test-runner-mock-fs
Open

test_runner: add mock file system API#65798
mcollina wants to merge 1 commit into
nodejs:mainfrom
mcollina:test-runner-mock-fs

Conversation

@mcollina

@mcollina mcollina commented Sep 4, 2026

Copy link
Copy Markdown
Member

Add t.mock.fs(): an in-memory mock file system for the test runner, backed by a mounted VirtualFileSystem.

The mock is mounted at a reserved mount point (${os.devNull}/vfs/<n>) assigned when it is created and exposed as mockFs.mountPoint, so it never shadows real files or directories. Files are accessible through the regular node:fs APIs and can be loaded with require() and import via the module loader integration.

test('reads configuration from a mock file', (t) => {
  const mockFs = t.mock.fs({
    files: {
      'config.json': JSON.stringify({ debug: true }),
    },
  });

  const config = JSON.parse(
    fs.readFileSync(path.join(mockFs.mountPoint, 'config.json'), 'utf8'));

  // addFile() returns the absolute path of the new file.
  const modPath = mockFs.addFile('mod.js', 'module.exports = 42;');
  assert.strictEqual(require(modPath), 42);
});

The returned MockFSContext exposes mountPoint, vfs, addFile(), addDirectory(), existsSync(), and restore(). Because mount points are assigned rather than chosen, addFile()/addDirectory() return the absolute path of what they created. The mock is unmounted automatically when the associated test finishes, like the other MockTracker APIs.

This adapts the mock fs concept originally proposed for the shadowing VFS design (where a prefix option mounted over real paths) to the non-shadowing implementation that landed in #63653.

🤖 Generated with Claude Code

https://claude.ai/code/session_01BuuR21ULqZEHoFmqWCnoyx

Add t.mock.fs(): an in-memory mock file system backed by a mounted
virtual file system. The mock lives at a reserved mount point exposed
as mountPoint, so it never shadows real files, and it is unmounted
automatically when the test finishes.

Signed-off-by: Matteo Collina <[email protected]>
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/test_runner

@nodejs-github-bot nodejs-github-bot added needs-ci PRs that need a full CI run. test_runner Issues and PRs related to the test runner subsystem. labels Sep 4, 2026
Comment thread doc/api/test.md
Adds a file to the mock file system. Missing parent directories are
created automatically.

### `mockFs.existsSync(path)`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why we'd want/need these separate APIs (like existsSync/addRirectory etc) the user can just call mockFs.vfs.mkdirSync can't they?

Comment thread doc/api/test.md
shadows real files or directories. Join it with relative paths to access
the mock's files through the `node:fs` APIs.

### `mockFs.restore()`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For restore to make sense here IMO the vfs would need to actually "take over" something like other mocks. I don't understand when I'd ever do this.

OTOH if mockFs could intercept/take over calls (i.e. like mock.module) it would make sense.

This is cool but I don't understand why I'd use this over mock.module("node:fs", { exports: new VirtualFileSystem() })

@benjamingr benjamingr left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm approving since the code itself looks fine and this is tagged early development and iteration is fine - but I'm not convinced this has a benefit over mock.module + VirtualFileSystem and I'm wary of adding more ways to e.g. create a file or directory since the current ones work with VirtualFileSystem as is

@codecov

codecov Bot commented Sep 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.13%. Comparing base (7551e1d) to head (1462eb5).
⚠️ Report is 15 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #65798      +/-   ##
==========================================
+ Coverage   90.05%   90.13%   +0.08%     
==========================================
  Files         769      769              
  Lines      261396   261765     +369     
  Branches    49631    49690      +59     
==========================================
+ Hits       235399   235946     +547     
+ Misses      17034    16852     -182     
- Partials     8963     8967       +4     
Files with missing lines Coverage Δ
lib/internal/test_runner/mock/mock.js 97.62% <100.00%> (+0.29%) ⬆️

... and 63 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-ci PRs that need a full CI run. test_runner Issues and PRs related to the test runner subsystem.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants