CtrlK
BlogDocsLog inGet started
Tessl Logo

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.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

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
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/mock-fs@5.5.x
Publish Source
CLI
Badge
tessl/npm-mock-fs badge