or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-mock-fs

A configurable mock file system for Node.js testing that replaces the built-in fs module with an in-memory implementation.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/mock-fs@5.5.x

To install, run

npx @tessl/cli install tessl/npm-mock-fs@5.5.0

index.mddocs/

mock-fs

mock-fs allows Node.js's built-in fs module to be backed temporarily by an in-memory, mock file system. This enables testing against a set of mock files and directories without requiring actual test fixtures on disk.

Requirements: Node.js 12.0.0 or higher

Package Information

  • Package Name: mock-fs
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install mock-fs --save-dev

Core Imports

const mock = require('mock-fs');

For ES modules:

import mock from 'mock-fs';

Basic Usage

const mock = require('mock-fs');

// Set up mock file system
mock({
  'path/to/fake/dir': {
    'some-file.txt': 'file content here',
    'empty-dir': {/** empty directory */}
  },
  'path/to/some.png': Buffer.from([8, 6, 7, 5, 3, 0, 9]),
  'some/other/path': {/** another empty directory */}
});

// Use regular fs operations
const fs = require('fs');
console.log(fs.readFileSync('path/to/fake/dir/some-file.txt', 'utf8'));

// Clean up
mock.restore();

Architecture

mock-fs works by replacing Node.js's internal file system bindings (process.binding('fs')) rather than patching the fs module directly. This approach:

  • Avoids conflicts with other libraries that patch fs (e.g., graceful-fs)
  • Works across multiple Node.js versions without copying Node's fs implementation
  • Maintains compatibility with libraries that use internal bindings

Key components:

  • FileSystem: Core in-memory file system implementation
  • Factory Functions: file(), directory(), symlink() for creating mock items with metadata
  • Loader: load() function for importing real files into the mock system
  • Bypass: bypass() function for temporarily accessing the real file system

Capabilities

Mock File System Setup

Configure the fs module to use an in-memory mock file system.

/**
 * Configure the fs module so it is backed by an in-memory file system
 * @param {Object} config - Mock file system configuration
 * @param {Object} [options] - Filesystem options
 * @param {boolean} [options.createCwd=true] - Create a directory for process.cwd()
 * @param {boolean} [options.createTmp=true] - Create a directory for os.tmpdir()
 */
function mock(config: Object, options?: {
  createCwd?: boolean;
  createTmp?: boolean;
}): void;

Usage Examples:

// Simple configuration with files and directories
mock({
  'file.txt': 'content',
  'dir': {
    'nested-file.txt': 'nested content'
  },
  'binary-file': Buffer.from([1, 2, 3, 4])
});

// Disable default directories
mock({
  'my-file.txt': 'content'
}, {
  createCwd: false,
  createTmp: false
});

File Factory

Create file objects with custom properties and metadata.

/**
 * Generate a factory for new files
 * @param {Object} [properties] - File configuration
 * @param {string|Buffer} [properties.content] - File contents
 * @param {number} [properties.mode=0666] - File mode (permission and sticky bits)
 * @param {number} [properties.uid] - User id (defaults to process.getuid())
 * @param {number} [properties.gid] - Group id (defaults to process.getgid())
 * @param {Date} [properties.atime] - Last access time (defaults to new Date())
 * @param {Date} [properties.ctime] - Last change time (defaults to new Date())
 * @param {Date} [properties.mtime] - Last modification time (defaults to new Date())
 * @param {Date} [properties.birthtime] - Creation time (defaults to new Date())
 * @param {number} [properties.atimeMs] - Access time in milliseconds
 * @param {number} [properties.ctimeMs] - Change time in milliseconds
 * @param {number} [properties.mtimeMs] - Modification time in milliseconds
 * @param {number} [properties.birthtimeMs] - Creation time in milliseconds
 * @returns {Function} Factory function that creates a new file
 */
mock.file(properties);

Usage Examples:

mock({
  'custom-file.txt': mock.file({
    content: 'file content',
    mode: 0644,
    mtime: new Date('2023-01-01'),
    uid: 1000,
    gid: 1000
  })
});

Directory Factory

Create directory objects with custom properties and nested items.

/**
 * Generate a factory for new directories
 * @param {Object} [properties] - Directory configuration
 * @param {number} [properties.mode=0777] - Directory mode (permission and sticky bits)
 * @param {number} [properties.uid] - User id (defaults to process.getuid())
 * @param {number} [properties.gid] - Group id (defaults to process.getgid())
 * @param {Date} [properties.atime] - Last access time (defaults to new Date())
 * @param {Date} [properties.ctime] - Last change time (defaults to new Date())
 * @param {Date} [properties.mtime] - Last modification time (defaults to new Date())
 * @param {Date} [properties.birthtime] - Creation time (defaults to new Date())
 * @param {number} [properties.atimeMs] - Access time in milliseconds
 * @param {number} [properties.ctimeMs] - Change time in milliseconds
 * @param {number} [properties.mtimeMs] - Modification time in milliseconds
 * @param {number} [properties.birthtimeMs] - Creation time in milliseconds
 * @param {Object} [properties.items] - Directory contents
 * @returns {Function} Factory function that creates a new directory
 */
mock.directory(properties);

Usage Examples:

mock({
  'custom-dir': mock.directory({
    mode: 0755,
    items: {
      'file1.txt': 'content 1',
      'file2.txt': 'content 2',
      'subdir': {}
    }
  })
});

Symbolic Link Factory

Create symbolic link objects with custom properties.

/**
 * Generate a factory for new symbolic links
 * @param {Object} properties - Symlink configuration
 * @param {string} properties.path - Path to the source (required)
 * @param {number} [properties.mode=0666] - Symlink mode (permission and sticky bits)
 * @param {number} [properties.uid] - User id (defaults to process.getuid())
 * @param {number} [properties.gid] - Group id (defaults to process.getgid())
 * @param {Date} [properties.atime] - Last access time (defaults to new Date())
 * @param {Date} [properties.ctime] - Last change time (defaults to new Date())
 * @param {Date} [properties.mtime] - Last modification time (defaults to new Date())
 * @param {Date} [properties.birthtime] - Creation time (defaults to new Date())
 * @param {number} [properties.atimeMs] - Access time in milliseconds
 * @param {number} [properties.ctimeMs] - Change time in milliseconds
 * @param {number} [properties.mtimeMs] - Modification time in milliseconds
 * @param {number} [properties.birthtimeMs] - Creation time in milliseconds
 * @returns {Function} Factory function that creates a new symbolic link
 */
mock.symlink(properties);

Usage Examples:

mock({
  'some/dir': {
    'regular-file': 'file contents',
    'a-symlink': mock.symlink({
      path: 'regular-file'
    })
  }
});

Load Real Files

Load real files and directories from the actual file system into the mock system.

/**
 * Load directory or file from real filesystem into mock system
 * @param {string} path - Path to real file or directory
 * @param {Object} [options] - Loading options
 * @param {boolean} [options.lazy=true] - File content isn't loaded until explicitly read
 * @param {boolean} [options.recursive=true] - Load all files and directories recursively
 * @returns {*} Mock file system item
 */
mock.load(path, options);

Usage Examples:

mock({
  // Lazy-load single file
  'my-file.txt': mock.load('/path/to/real/file.txt'),
  
  // Pre-load JavaScript file
  'ready.js': mock.load('/path/to/script.js', { lazy: false }),
  
  // Load entire directory
  'node_modules': mock.load('/path/to/node_modules'),
  
  // Load directory without subdirectories, pre-loading content
  'configs': mock.load('/etc/configs', { 
    recursive: false, 
    lazy: false 
  })
});

File System Restoration

Restore the real file system, undoing the effects of mock().

/**
 * Restore the fs binding to the real file system
 * This undoes the effect of calling mock()
 */
mock.restore();

Usage Examples:

// Typical test setup
beforeEach(() => {
  mock({
    'test-file': 'content'
  });
});

afterEach(() => {
  mock.restore();
});

// Or manual cleanup
mock({ 'temp-file': 'data' });
// ... do work
mock.restore();

Bypass Mock File System

Execute operations on the real file system while mock is active.

/**
 * Perform action, bypassing mock filesystem
 * Supports both synchronous and asynchronous functions
 * @param {Function} fn - Function to execute with real filesystem access
 * @returns {*} Result of executing fn, or Promise if fn returns Promise
 */
mock.bypass(fn);

Usage Examples:

// Read from real filesystem while mock is active
const realData = mock.bypass(() => {
  return fs.readFileSync('/real/path/file.txt', 'utf-8');
});

// Async operations (returns Promise)
const asyncData = await mock.bypass(async () => {
  const stats = await fs.promises.stat('/real/file.txt');
  const data = await fs.promises.readFile('/real/file.txt');
  return { stats, data };
});

Get Mock Root

Access the internal mock file system root object.

/**
 * Get hold of the mocked filesystem's root
 * Returns empty object if fs hasn't currently been replaced
 * @returns {Object} The mock root directory object
 */
mock.getMockRoot();

Usage Examples:

mock({ 'test-file': 'content' });
const root = mock.getMockRoot();
console.log(root); // Mock filesystem root object

mock.restore();
console.log(mock.getMockRoot()); // {}

Error Handling

mock-fs throws standard Node.js filesystem errors that match the real fs module behavior:

  • ENOENT: File or directory not found
  • ENOTDIR: Not a directory (when trying to traverse through a file)
  • EACCES: Permission denied (when file/directory permissions prevent access)
  • EEXIST: File already exists

Platform Considerations

  • Windows: File mode permissions have no effect (Windows doesn't use POSIX permissions)
  • POSIX Systems: File access is controlled based on mode, process.getuid(), and process.getgid()
  • Path Separators: Always use forward slashes (/) in mock configuration, even on Windows
  • Case Sensitivity: Follows the platform's filesystem case sensitivity rules

Testing Integration

Jest Snapshot Testing

When using Jest snapshots, restore the mock before snapshot comparison:

const actual = testedFunction();
mock.restore(); // Must restore before snapshot matching
expect(actual).toMatchSnapshot();

Mocha/Other Test Frameworks

describe('My Tests', () => {
  beforeEach(() => {
    mock({
      'test-data.json': '{"key": "value"}',
      'empty-dir': {}
    });
  });
  
  afterEach(() => {
    mock.restore();
  });
  
  it('should read mock file', () => {
    const data = fs.readFileSync('test-data.json', 'utf-8');
    expect(JSON.parse(data)).to.deep.equal({ key: 'value' });
  });
});

Compatibility Notes

  • Compatible with graceful-fs@4.x (not compatible with graceful-fs@3.x)
  • Requires Node.js 12+
  • Must be required before other modules that modify fs for best compatibility
  • Works with both CommonJS and ES modules
  • Compatible with fs.promises API and stream-based operations