0
# mock-fs
1
2
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.
3
4
**Requirements:** Node.js 12.0.0 or higher
5
6
## Package Information
7
8
- **Package Name**: mock-fs
9
- **Package Type**: npm
10
- **Language**: JavaScript
11
- **Installation**: `npm install mock-fs --save-dev`
12
13
## Core Imports
14
15
```javascript
16
const mock = require('mock-fs');
17
```
18
19
For ES modules:
20
21
```javascript
22
import mock from 'mock-fs';
23
```
24
25
## Basic Usage
26
27
```javascript
28
const mock = require('mock-fs');
29
30
// Set up mock file system
31
mock({
32
'path/to/fake/dir': {
33
'some-file.txt': 'file content here',
34
'empty-dir': {/** empty directory */}
35
},
36
'path/to/some.png': Buffer.from([8, 6, 7, 5, 3, 0, 9]),
37
'some/other/path': {/** another empty directory */}
38
});
39
40
// Use regular fs operations
41
const fs = require('fs');
42
console.log(fs.readFileSync('path/to/fake/dir/some-file.txt', 'utf8'));
43
44
// Clean up
45
mock.restore();
46
```
47
48
## Architecture
49
50
mock-fs works by replacing Node.js's internal file system bindings (`process.binding('fs')`) rather than patching the `fs` module directly. This approach:
51
52
- Avoids conflicts with other libraries that patch `fs` (e.g., `graceful-fs`)
53
- Works across multiple Node.js versions without copying Node's `fs` implementation
54
- Maintains compatibility with libraries that use internal bindings
55
56
Key components:
57
- **FileSystem**: Core in-memory file system implementation
58
- **Factory Functions**: `file()`, `directory()`, `symlink()` for creating mock items with metadata
59
- **Loader**: `load()` function for importing real files into the mock system
60
- **Bypass**: `bypass()` function for temporarily accessing the real file system
61
62
## Capabilities
63
64
### Mock File System Setup
65
66
Configure the fs module to use an in-memory mock file system.
67
68
```javascript { .api }
69
/**
70
* Configure the fs module so it is backed by an in-memory file system
71
* @param {Object} config - Mock file system configuration
72
* @param {Object} [options] - Filesystem options
73
* @param {boolean} [options.createCwd=true] - Create a directory for process.cwd()
74
* @param {boolean} [options.createTmp=true] - Create a directory for os.tmpdir()
75
*/
76
function mock(config: Object, options?: {
77
createCwd?: boolean;
78
createTmp?: boolean;
79
}): void;
80
```
81
82
**Usage Examples:**
83
84
```javascript
85
// Simple configuration with files and directories
86
mock({
87
'file.txt': 'content',
88
'dir': {
89
'nested-file.txt': 'nested content'
90
},
91
'binary-file': Buffer.from([1, 2, 3, 4])
92
});
93
94
// Disable default directories
95
mock({
96
'my-file.txt': 'content'
97
}, {
98
createCwd: false,
99
createTmp: false
100
});
101
```
102
103
### File Factory
104
105
Create file objects with custom properties and metadata.
106
107
```javascript { .api }
108
/**
109
* Generate a factory for new files
110
* @param {Object} [properties] - File configuration
111
* @param {string|Buffer} [properties.content] - File contents
112
* @param {number} [properties.mode=0666] - File mode (permission and sticky bits)
113
* @param {number} [properties.uid] - User id (defaults to process.getuid())
114
* @param {number} [properties.gid] - Group id (defaults to process.getgid())
115
* @param {Date} [properties.atime] - Last access time (defaults to new Date())
116
* @param {Date} [properties.ctime] - Last change time (defaults to new Date())
117
* @param {Date} [properties.mtime] - Last modification time (defaults to new Date())
118
* @param {Date} [properties.birthtime] - Creation time (defaults to new Date())
119
* @param {number} [properties.atimeMs] - Access time in milliseconds
120
* @param {number} [properties.ctimeMs] - Change time in milliseconds
121
* @param {number} [properties.mtimeMs] - Modification time in milliseconds
122
* @param {number} [properties.birthtimeMs] - Creation time in milliseconds
123
* @returns {Function} Factory function that creates a new file
124
*/
125
mock.file(properties);
126
```
127
128
**Usage Examples:**
129
130
```javascript
131
mock({
132
'custom-file.txt': mock.file({
133
content: 'file content',
134
mode: 0644,
135
mtime: new Date('2023-01-01'),
136
uid: 1000,
137
gid: 1000
138
})
139
});
140
```
141
142
### Directory Factory
143
144
Create directory objects with custom properties and nested items.
145
146
```javascript { .api }
147
/**
148
* Generate a factory for new directories
149
* @param {Object} [properties] - Directory configuration
150
* @param {number} [properties.mode=0777] - Directory mode (permission and sticky bits)
151
* @param {number} [properties.uid] - User id (defaults to process.getuid())
152
* @param {number} [properties.gid] - Group id (defaults to process.getgid())
153
* @param {Date} [properties.atime] - Last access time (defaults to new Date())
154
* @param {Date} [properties.ctime] - Last change time (defaults to new Date())
155
* @param {Date} [properties.mtime] - Last modification time (defaults to new Date())
156
* @param {Date} [properties.birthtime] - Creation time (defaults to new Date())
157
* @param {number} [properties.atimeMs] - Access time in milliseconds
158
* @param {number} [properties.ctimeMs] - Change time in milliseconds
159
* @param {number} [properties.mtimeMs] - Modification time in milliseconds
160
* @param {number} [properties.birthtimeMs] - Creation time in milliseconds
161
* @param {Object} [properties.items] - Directory contents
162
* @returns {Function} Factory function that creates a new directory
163
*/
164
mock.directory(properties);
165
```
166
167
**Usage Examples:**
168
169
```javascript
170
mock({
171
'custom-dir': mock.directory({
172
mode: 0755,
173
items: {
174
'file1.txt': 'content 1',
175
'file2.txt': 'content 2',
176
'subdir': {}
177
}
178
})
179
});
180
```
181
182
### Symbolic Link Factory
183
184
Create symbolic link objects with custom properties.
185
186
```javascript { .api }
187
/**
188
* Generate a factory for new symbolic links
189
* @param {Object} properties - Symlink configuration
190
* @param {string} properties.path - Path to the source (required)
191
* @param {number} [properties.mode=0666] - Symlink mode (permission and sticky bits)
192
* @param {number} [properties.uid] - User id (defaults to process.getuid())
193
* @param {number} [properties.gid] - Group id (defaults to process.getgid())
194
* @param {Date} [properties.atime] - Last access time (defaults to new Date())
195
* @param {Date} [properties.ctime] - Last change time (defaults to new Date())
196
* @param {Date} [properties.mtime] - Last modification time (defaults to new Date())
197
* @param {Date} [properties.birthtime] - Creation time (defaults to new Date())
198
* @param {number} [properties.atimeMs] - Access time in milliseconds
199
* @param {number} [properties.ctimeMs] - Change time in milliseconds
200
* @param {number} [properties.mtimeMs] - Modification time in milliseconds
201
* @param {number} [properties.birthtimeMs] - Creation time in milliseconds
202
* @returns {Function} Factory function that creates a new symbolic link
203
*/
204
mock.symlink(properties);
205
```
206
207
**Usage Examples:**
208
209
```javascript
210
mock({
211
'some/dir': {
212
'regular-file': 'file contents',
213
'a-symlink': mock.symlink({
214
path: 'regular-file'
215
})
216
}
217
});
218
```
219
220
### Load Real Files
221
222
Load real files and directories from the actual file system into the mock system.
223
224
```javascript { .api }
225
/**
226
* Load directory or file from real filesystem into mock system
227
* @param {string} path - Path to real file or directory
228
* @param {Object} [options] - Loading options
229
* @param {boolean} [options.lazy=true] - File content isn't loaded until explicitly read
230
* @param {boolean} [options.recursive=true] - Load all files and directories recursively
231
* @returns {*} Mock file system item
232
*/
233
mock.load(path, options);
234
```
235
236
**Usage Examples:**
237
238
```javascript
239
mock({
240
// Lazy-load single file
241
'my-file.txt': mock.load('/path/to/real/file.txt'),
242
243
// Pre-load JavaScript file
244
'ready.js': mock.load('/path/to/script.js', { lazy: false }),
245
246
// Load entire directory
247
'node_modules': mock.load('/path/to/node_modules'),
248
249
// Load directory without subdirectories, pre-loading content
250
'configs': mock.load('/etc/configs', {
251
recursive: false,
252
lazy: false
253
})
254
});
255
```
256
257
### File System Restoration
258
259
Restore the real file system, undoing the effects of mock().
260
261
```javascript { .api }
262
/**
263
* Restore the fs binding to the real file system
264
* This undoes the effect of calling mock()
265
*/
266
mock.restore();
267
```
268
269
**Usage Examples:**
270
271
```javascript
272
// Typical test setup
273
beforeEach(() => {
274
mock({
275
'test-file': 'content'
276
});
277
});
278
279
afterEach(() => {
280
mock.restore();
281
});
282
283
// Or manual cleanup
284
mock({ 'temp-file': 'data' });
285
// ... do work
286
mock.restore();
287
```
288
289
### Bypass Mock File System
290
291
Execute operations on the real file system while mock is active.
292
293
```javascript { .api }
294
/**
295
* Perform action, bypassing mock filesystem
296
* Supports both synchronous and asynchronous functions
297
* @param {Function} fn - Function to execute with real filesystem access
298
* @returns {*} Result of executing fn, or Promise if fn returns Promise
299
*/
300
mock.bypass(fn);
301
```
302
303
**Usage Examples:**
304
305
```javascript
306
// Read from real filesystem while mock is active
307
const realData = mock.bypass(() => {
308
return fs.readFileSync('/real/path/file.txt', 'utf-8');
309
});
310
311
// Async operations (returns Promise)
312
const asyncData = await mock.bypass(async () => {
313
const stats = await fs.promises.stat('/real/file.txt');
314
const data = await fs.promises.readFile('/real/file.txt');
315
return { stats, data };
316
});
317
```
318
319
### Get Mock Root
320
321
Access the internal mock file system root object.
322
323
```javascript { .api }
324
/**
325
* Get hold of the mocked filesystem's root
326
* Returns empty object if fs hasn't currently been replaced
327
* @returns {Object} The mock root directory object
328
*/
329
mock.getMockRoot();
330
```
331
332
**Usage Examples:**
333
334
```javascript
335
mock({ 'test-file': 'content' });
336
const root = mock.getMockRoot();
337
console.log(root); // Mock filesystem root object
338
339
mock.restore();
340
console.log(mock.getMockRoot()); // {}
341
```
342
343
## Error Handling
344
345
mock-fs throws standard Node.js filesystem errors that match the real `fs` module behavior:
346
347
- `ENOENT`: File or directory not found
348
- `ENOTDIR`: Not a directory (when trying to traverse through a file)
349
- `EACCES`: Permission denied (when file/directory permissions prevent access)
350
- `EEXIST`: File already exists
351
352
## Platform Considerations
353
354
- **Windows**: File mode permissions have no effect (Windows doesn't use POSIX permissions)
355
- **POSIX Systems**: File access is controlled based on `mode`, `process.getuid()`, and `process.getgid()`
356
- **Path Separators**: Always use forward slashes (`/`) in mock configuration, even on Windows
357
- **Case Sensitivity**: Follows the platform's filesystem case sensitivity rules
358
359
## Testing Integration
360
361
### Jest Snapshot Testing
362
363
When using Jest snapshots, restore the mock before snapshot comparison:
364
365
```javascript
366
const actual = testedFunction();
367
mock.restore(); // Must restore before snapshot matching
368
expect(actual).toMatchSnapshot();
369
```
370
371
### Mocha/Other Test Frameworks
372
373
```javascript
374
describe('My Tests', () => {
375
beforeEach(() => {
376
mock({
377
'test-data.json': '{"key": "value"}',
378
'empty-dir': {}
379
});
380
});
381
382
afterEach(() => {
383
mock.restore();
384
});
385
386
it('should read mock file', () => {
387
const data = fs.readFileSync('test-data.json', 'utf-8');
388
expect(JSON.parse(data)).to.deep.equal({ key: 'value' });
389
});
390
});
391
```
392
393
## Compatibility Notes
394
395
- Compatible with `graceful-fs@4.x` (not compatible with `graceful-fs@3.x`)
396
- Requires Node.js 12+
397
- Must be required before other modules that modify `fs` for best compatibility
398
- Works with both CommonJS and ES modules
399
- Compatible with `fs.promises` API and stream-based operations