Description
The recursive
option on fs.readdirSync
is not working as expected when using mock-fs
.
version: "mock-fs": "^5.5.0"
Failing test with mock-fs
This test should pass but it doesn't.
import { expect, test } from '@jest/globals';
import fs from 'fs';
import mockFS from 'mock-fs';
beforeEach(function () {
mockFS({
'path/to/example': {
'file1.txt': 'file contents',
dir: {
'file2.txt': 'file contents',
subdir: {
'file3.txt': 'file contents'
}
}
}
});
});
afterEach(mockFS.restore);
test.only('get mocked files', () => {
const files = fs.readdirSync('./path/to/example/', {
recursive: true
});
expect(files).toEqual([
'dir',
'file1.txt',
'dir/file2.txt',
'dir/subdir',
'dir/subdir/file3.txt'
]);
});
Test results:
> jest "test/test.spec.ts"
FAIL test/test.spec.ts
✕ get mocked files (3 ms)
● get mocked files
expect(received).toEqual(expected) // deep equality
- Expected - 3
+ Received + 0
Array [
"dir",
"file1.txt",
- "dir/file2.txt",
- "dir/subdir",
- "dir/subdir/file3.txt",
]
23 | recursive: true
24 | });
> 25 | expect(files).toEqual([
| ^
26 | 'dir',
27 | 'file1.txt',
28 | 'dir/file2.txt',
at Object.<anonymous> (test/test.spec.ts:25:17)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: 0.117 s, estimated 1 s
Ran all test suites matching /test\/test.spec.ts/i.
ELIFECYCLE Test failed. See above for more details.
Passing test with fs
I commented out the mock-fs
configuration and I created the same directory structure on my system. I ran the test again and I got the the test passed. So we know fs.readdirSync
is working.
- ./path/to/example/
- file1.txt
- dir/
- file2.txt
- subdir/
- file3.txt
import { expect, test } from '@jest/globals';
import fs from 'fs';
// import mockFS from 'mock-fs';
// beforeEach(function () {
// mockFS({
// 'path/to/example': {
// 'file1.txt': 'file contents',
// dir: {
// 'file2.txt': 'file contents',
// subdir: {
// 'file3.txt': 'file contents'
// }
// }
// }
// });
// });
// afterEach(mockFS.restore);
test.only('get mocked files', () => {
const files = fs.readdirSync('./path/to/example/', {
recursive: true
});
expect(files).toEqual([
'dir',
'file1.txt',
'dir/file2.txt',
'dir/subdir',
'dir/subdir/file3.txt'
]);
});
Test results:
> jest "test/test.spec.ts"
PASS test/test.spec.ts
✓ get mocked files (2 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.095 s, estimated 1 s
Ran all test suites matching /test\/test.spec.ts/i.
Its a trap!
After testing the native fs
I removed the comments to re-enable mock-fs
and now the test is passing with mocks. As it turns out it is still looking into the ./path/to/example/
directory I created on my filesystem.
It looks like mock-fs
is still adding the mocked files into the list and fs
merges any remaining on top.
If I add another file to the mock path at this point it fails with 1 extra file in the list.
mockFS({
'path/to/example': {
'file1.txt': 'file contents',
dir: {
'file2.txt': 'file contents',
subdir: {
'file3.txt': 'file contents',
'file4.txt': 'file contents' // <-- Extra
}
}
}
});
> jest "test/test.spec.ts"
FAIL test/test.spec.ts
✕ get mocked files (4 ms)
● get mocked files
expect(received).toEqual(expected) // deep equality
- Expected - 0
+ Received + 1
@@ -2,6 +2,7 @@
"dir",
"file1.txt",
"dir/file2.txt",
"dir/subdir",
"dir/subdir/file3.txt",
+ "dir/subdir/file4.txt",
]
24 | recursive: true
25 | });
> 26 | expect(files).toEqual([
| ^
27 | 'dir',
28 | 'file1.txt',
29 | 'dir/file2.txt',
at Object.<anonymous> (test/test.spec.ts:26:17)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: 0.137 s, estimated 1 s
Ran all test suites matching /test\/test.spec.ts/i.
ELIFECYCLE Test failed. See above for more details.
But if I remove the directory from my filesystem it goes back to missing all of the recursive directories again and doesn't show the extra file4.txt
I added above.
> jest "test/test.spec.ts"
FAIL test/test.spec.ts
✕ get mocked files (3 ms)
● get mocked files
expect(received).toEqual(expected) // deep equality
- Expected - 3
+ Received + 0
Array [
"dir",
"file1.txt",
- "dir/file2.txt",
- "dir/subdir",
- "dir/subdir/file3.txt",
]
24 | recursive: true
25 | });
> 26 | expect(files).toEqual([
| ^
27 | 'dir',
28 | 'file1.txt',
29 | 'dir/file2.txt',
at Object.<anonymous> (test/test.spec.ts:26:17)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: 0.119 s, estimated 1 s
Ran all test suites matching /test\/test.spec.ts/i.
ELIFECYCLE Test failed. See above for more details.