UNPKG

10.6 kBMarkdownView Raw
1# `mock-fs`
2
3The `mock-fs` module allows Node's built-in [`fs` module](http://nodejs.org/api/fs.html) to be backed temporarily by an in-memory, mock file system. This lets you run tests against a set of mock files and directories instead of lugging around a bunch of test fixtures.
4
5## Example
6
7The code below makes it so the `fs` module is temporarily backed by a mock file system with a few files and directories.
8
9```js
10var mock = require('mock-fs');
11
12mock({
13 'path/to/fake/dir': {
14 'some-file.txt': 'file content here',
15 'empty-dir': {/** empty directory */}
16 },
17 'path/to/some.png': new Buffer([8, 6, 7, 5, 3, 0, 9]),
18 'some/other/path': {/** another empty directory */}
19});
20```
21
22When you are ready to restore the `fs` module (so that it is backed by your real file system), call [`mock.restore()`](#mockrestore).
23
24```js
25// after a test runs
26mock.restore();
27```
28
29## Docs
30
31### <a id='mockconfig'>`mock(config)`</a>
32
33Configure the `fs` module so it is backed by an in-memory file system.
34
35Calling `mock` sets up a mock file system with at least two directories: `process.cwd()` and `os.tmpdir()` (or `os.tmpDir()` for older Node). When called with no arguments, just these two directories are created. When called with a `config` object, additional files, directories, and symlinks are created.
36
37Property names of the `config` object are interpreted as relative paths to resources (relative from `process.cwd()`). Property values of the `config` object are interpreted as content or configuration for the generated resources.
38
39*Note that paths should always use forward slashes (`/`) - even on Windows.*
40
41### Creating files
42
43When `config` property values are a `string` or `Buffer`, a file is created with the provided content. For example, the following configuration creates a single file with string content (in addition to the two default directories).
44```js
45mock({
46 'path/to/file.txt': 'file content here'
47});
48```
49
50To create a file with additional properties (owner, permissions, atime, etc.), use the [`mock.file()`](#mockfileproperties) function described below.
51
52### <a id='mockfileproperties'>`mock.file(properties)`</a>
53
54Create a factory for new files. Supported properties:
55
56 * **content** - `string|Buffer` File contents.
57 * **mode** - `number` File mode (permission and sticky bits). Defaults to `0666`.
58 * **uid** - `number` The user id. Defaults to `process.getuid()`.
59 * **gid** - `number` The group id. Defaults to `process.getgid()`.
60 * **atime** - `Date` The last file access time. Defaults to `new Date()`. Updated when file contents are accessed.
61 * **ctime** - `Date` The last file change time. Defaults to `new Date()`. Updated when file owner or permissions change.
62 * **mtime** - `Date` The last file modification time. Defaults to `new Date()`. Updated when file contents change.
63 * **birthtime** - `Date` The time of file creation. Defaults to `new Date()`.
64
65To create a mock filesystem with a very old file named `foo`, you could do something like this:
66```js
67mock({
68 foo: mock.file({
69 content: 'file content here',
70 ctime: new Date(1),
71 mtime: new Date(1)
72 })
73});
74```
75
76Note that if you want to create a file with the default properties, you can provide a `string` or `Buffer` directly instead of calling `mock.file()`.
77
78### Creating directories
79
80When `config` property values are an `Object`, a directory is created. The structure of the object is the same as the `config` object itself. So an empty directory can be created with a simple object literal (`{}`). The following configuration creates a directory containing two files (in addition to the two default directories):
81```js
82// note that this could also be written as
83// mock({'path/to/dir': { /** config */ }})
84mock({
85 path: {
86 to: {
87 dir: {
88 file1: 'text content',
89 file2: new Buffer([1, 2, 3, 4])
90 }
91 }
92 }
93});
94```
95
96To create a directory with additional properties (owner, permissions, atime, etc.), use the [`mock.directory()`](mockdirectoryproperties) function described below.
97
98### <a id='mockdirectoryproperties'>`mock.directory(properties)`</a>
99
100Create a factory for new directories. Supported properties:
101
102 * **mode** - `number` Directory mode (permission and sticky bits). Defaults to `0777`.
103 * **uid** - `number` The user id. Defaults to `process.getuid()`.
104 * **gid** - `number` The group id. Defaults to `process.getgid()`.
105 * **atime** - `Date` The last directory access time. Defaults to `new Date()`.
106 * **ctime** - `Date` The last directory change time. Defaults to `new Date()`. Updated when owner or permissions change.
107 * **mtime** - `Date` The last directory modification time. Defaults to `new Date()`. Updated when an item is added, removed, or renamed.
108 * **birthtime** - `Date` The time of directory creation. Defaults to `new Date()`.
109 * **items** - `Object` Directory contents. Members will generate additional files, directories, or symlinks.
110
111To create a mock filesystem with a directory with the relative path `some/dir` that has a mode of `0755` and two child files, you could do something like this:
112```js
113mock({
114 'some/dir': mock.directory({
115 mode: 0755,
116 items: {
117 file1: 'file one content',
118 file2: new Buffer([8, 6, 7, 5, 3, 0, 9])
119 }
120 })
121});
122```
123
124Note that if you want to create a directory with the default properties, you can provide an `Object` directly instead of calling `mock.directory()`.
125
126### Creating symlinks
127
128Using a `string` or a `Buffer` is a shortcut for creating files with default properties. Using an `Object` is a shortcut for creating a directory with default properties. There is no shortcut for creating symlinks. To create a symlink, you need to call the [`mock.symlink()`](#mocksymlinkproperties) function described below.
129
130### <a id='mocksymlinkproperties'>`mock.symlink(properties)`</a>
131
132Create a factory for new symlinks. Supported properties:
133
134 * **path** - `string` Path to the source (required).
135 * **mode** - `number` Symlink mode (permission and sticky bits). Defaults to `0666`.
136 * **uid** - `number` The user id. Defaults to `process.getuid()`.
137 * **gid** - `number` The group id. Defaults to `process.getgid()`.
138 * **atime** - `Date` The last symlink access time. Defaults to `new Date()`.
139 * **ctime** - `Date` The last symlink change time. Defaults to `new Date()`.
140 * **mtime** - `Date` The last symlink modification time. Defaults to `new Date()`.
141 * **birthtime** - `Date` The time of symlink creation. Defaults to `new Date()`.
142
143To create a mock filesystem with a file and a symlink, you could do something like this:
144```js
145mock({
146 'some/dir': {
147 'regular-file': 'file contents',
148 'a-symlink': mock.symlink({
149 path: 'regular-file'
150 })
151 }
152});
153```
154
155### Restoring the file system
156
157### <a id='mockrestore'>`mock.restore()`</a>
158
159Restore the `fs` binding to the real file system. This undoes the effect of calling `mock()`. Typically, you would set up a mock file system before running a test and restore the original after. Using a test runner with `beforeEach` and `afterEach` hooks, this might look like the following:
160
161```js
162beforeEach(function() {
163 mock({
164 'fake-file': 'file contents'
165 });
166});
167afterEach(mock.restore);
168```
169
170### Creating a new `fs` module instead of modifying the original
171
172### <a id='mockfsconfig'>`mock.fs(config)`</a>
173
174Calling `mock()` modifies Node's built-in `fs` module. This is useful when you want to test with a mock file system. If for some reason you want to work with the real file system and an in-memory version at the same time, you can call the `mock.fs()` function. This takes the same `config` object [described above](#mockconfig) and sets up a in-memory file system. Instead of modifying the binding for the built-in `fs` module (as is done when calling `mock(config)`), the `mock.fs(config)` function returns an object with the same interface as the `fs` module, but backed by your mock file system.
175
176## Install
177
178Using `npm`:
179
180```
181npm install mock-fs --save-dev
182```
183
184## Caveats
185
186### Using with other modules that modify `fs`
187
188When you require `mock-fs`, Node's own `fs` module is patched to allow the binding to the underlying file system to be swapped out. If you require `mock-fs` *before* any other modules that modify `fs` (e.g. `graceful-fs`), the mock should behave as expected.
189
190**Note** `mock-fs` is not compatible with `graceful-fs@3.x` but works with `graceful-fs@4.x`.
191
192### `fs` overrides
193
194The following [`fs` functions](http://nodejs.org/api/fs.html) are overridden: `fs.ReadStream`, `fs.Stats`, `fs.WriteStream`, `fs.appendFile`, `fs.appendFileSync`, `fs.chmod`, `fs.chmodSync`, `fs.chown`, `fs.chownSync`, `fs.close`, `fs.closeSync`, `fs.createReadStream`, `fs.createWriteStream`, `fs.exists`, `fs.existsSync`, `fs.fchmod`, `fs.fchmodSync`, `fs.fchown`, `fs.fchownSync`, `fs.fdatasync`, `fs.fdatasyncSync`, `fs.fstat`, `fs.fstatSync`, `fs.fsync`, `fs.fsyncSync`, `fs.ftruncate`, `fs.ftruncateSync`, `fs.futimes`, `fs.futimesSync`, `fs.lchmod`, `fs.lchmodSync`, `fs.lchown`, `fs.lchownSync`, `fs.link`, `fs.linkSync`, `fs.lstatSync`, `fs.lstat`, `fs.mkdir`, `fs.mkdirSync`, `fs.open`, `fs.openSync`, `fs.read`, `fs.readSync`, `fs.readFile`, `fs.readFileSync`, `fs.readdir`, `fs.readdirSync`, `fs.readlink`, `fs.readlinkSync`, `fs.realpath`, `fs.realpathSync`, `fs.rename`, `fs.renameSync`, `fs.rmdir`, `fs.rmdirSync`, `fs.stat`, `fs.statSync`, `fs.symlink`, `fs.symlinkSync`, `fs.truncate`, `fs.truncateSync`, `fs.unlink`, `fs.unlinkSync`, `fs.utimes`, `fs.utimesSync`, `fs.write`, `fs.writeSync`, `fs.writeFile`, and `fs.writeFileSync`.
195
196Mock `fs.Stats` objects have the following properties: `dev`, `ino`, `nlink`, `mode`, `size`, `rdev`, `blksize`, `blocks`, `atime`, `ctime`, `mtime`, `birthtime`, `uid`, and `gid`. In addition, all of the `is*()` method are provided (e.g. `isDirectory()`, `isFile()`, et al.).
197
198Mock file access is controlled based on file mode where `process.getuid()` and `process.getgid()` are available (POSIX systems). On other systems (e.g. Windows) the file mode has no effect.
199
200The following `fs` functions are *not* currently mocked (if your tests use these, they will work against the real file system): `fs.FSWatcher`, `fs.unwatchFile`, `fs.watch`, and `fs.watchFile`. Pull requests welcome.
201
202Tested on Linux, OSX, and Windows using Node 0.8, 0.9, 0.10, 0.11, & 0.12 and io.js 1.1, 2.0 & 3.0. Check the tickets for a list of [known issues](https://github.com/tschaub/mock-fs/issues).
203
204[![Current Status](https://secure.travis-ci.org/tschaub/mock-fs.png?branch=master)](https://travis-ci.org/tschaub/mock-fs)