You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
For those like me who came here in a panic because their tests started failing, I had success (and minimal effort) replacing mock-fs with memfs.
Do you mind post some examples please? I'm trying to use memfs but I'm struggling with it. I found an basic example with jest however, i'm using chai so nothing is working
@PedroS11 I also decided to switch using memfs. For me, it was mostly a matter of switching mockFS({. . .}) with vol.fromNestedJSON({. . .}) and changing mockFS.restore() to vol.reset()
So for example (I am using vitest in this but jest should be pretty close as well)
@PedroS11 I also decided to switch using memfs. For me, it was mostly a matter of switching mockFS({. . .}) with vol.fromNestedJSON({. . .}) and changing mockFS.restore() to vol.reset()
So for example (I am using vitest in this but jest should be pretty close as well)
import{fs,vol}from"memfs";import{afterEach,beforeEach,describe,expect,test}from"vitest";describe("some test",()=>{beforeEach(()=>{vol.fromNestedJSON({// <-- Changed this from mockFSProjects: {"Projects - 23": {"Test Client": {"Projects 1": {"Sub folder": {},},},},"Projects - 24": {},},});});afterEach(()=>{vol.reset();// <-- changed this from mockFS.restore();});test("project folder creation",()=>{constprojectFolderPath=path.join("Projects","Projects - 23","Test Client","Projects 2",);constresult=_createProjectFolder(projectFolderPath,projectTemplatePath);expect(result).toEqual({path: projectFolderPath,error: null});});});
I hope that helps!
Thank you for this snippet @JBloss1517 !! in the following weeks, I'll try to migrate too and I'll see how it works. I'll leave my progress here when I start so it helps everyone with this struggle
I was having issues with my Jest tests still using the built-in fs instead of the memfs implementation. This worked to mock out fs & fs/promises:
import { fs, vol } from 'memfs'
// import needs to match what you used in your code
jest.mock('fs', () => fs)
jest.mock('fs/promises', () => fs.promises)
// test code
Here's an example of migrating a mock-fs test that used mock.load() to memfs. The test itself doesn't change. Just adding a vi.mock() and changing the beforeEach() and afterEach().
Before with mock-fs:
import mock from 'mock-fs'
import fs from 'fs'
import { describe, test, expect, beforeEach, afterEach } from 'vitest'
describe('test', () => {
beforeEach(() => {
mock({
test: {
'UnitTestInput.xlsx': mock.load(path.resolve(__dirname, '../test/UnitTestInput.xlsx'), { lazy: false })
another: {
path: {
'data.json': '{ "fakeData": "yes" }'
}
}
}
})
})
afterEach(() => {
mock.restore()
})
test('myUtility.run() processes test file and creates output', () => {
// given:
const myUtility = new MyUtility()
// when: we run the utility
myUtility.run(`${process.cwd()}/test/UnitTestInput.xlsx`)
// then: output is generated and matches snapshot
expect(fs.readFileSync(`${process.cwd()}/test/another/path/data-generated.json`, 'utf8')).toMatchSnapshot()
expect(fs.existsSync(`${process.cwd()}/test/report-UnitTestInput.txt`)).toBeTruthy()
})
})
After with memfs:
import { vol, fs } from "memfs";
import { vi, describe, test, expect, beforeEach, afterEach } from 'vitest'
// Mock fs everywhere else with the memfs version.
vi.mock('fs', async () => {
const memfs = await vi.importActual('memfs')
// Support both `import fs from "fs"` and "import { readFileSync } from "fs"`
return { default: memfs.fs, ...memfs.fs }
})
describe('test', () => {
beforeEach(async () => {
// Get the real fs method, read the real file, and inject into the memory file system.
const fs = await vi.importActual('fs')
const unitTestInputXlsx = fs.readFileSync(path.resolve(__dirname, '../test/UnitTestInput.xlsx'))
vol.fromNestedJSON({
test: {
'UnitTestInput.xlsx': unitTestInputXlsx,
another: {
path: {
'data.json': '{ "fakeData": "yes" }'
}
}
}
})
})
afterEach(() => {
vol.reset()
})
test('myUtility.run() processes test file and creates output', () => {
// given:
const myUtility = new MyUtility()
// when: we run the utility
myUtility.run(`${process.cwd()}/test/UnitTestInput.xlsx`)
// then: output is generated and matches snapshot
expect(fs.readFileSync(`${process.cwd()}/test/another/path/data-generated.json`, 'utf8')).toMatchSnapshot()
expect(fs.existsSync(`${process.cwd()}/test/report-UnitTestInput.txt`)).toBeTruthy()
})
})
I was having issues with my Jest tests still using the built-in fs instead of the memfs implementation. This worked to mock out fs & fs/promises:
import { fs, vol } from 'memfs'
// import needs to match what you used in your code
jest.mock('fs', () => fs)
jest.mock('fs/promises', () => fs.promises)
// test code
In mocha there is a little more work required, because it does not include a mocking system of its own. Usually you use the excellent Sinon for mocking, but in this special case this won't work since, by specification, imports must be unalterable. Instead, I use esmock to mock out modules. Something like this works for me:
// Note we DO NOT import the system under test here
import { vol } from 'memfs';
describe('test', function() {
let sut;
before(async function() {
sut = (await esmock('../path/to/sut.js', {}, {
'fs': vol,
'fs/promises': vol.promisesApi
})).default;
});
beforeEach(function() {
vol.fromNestedJSON({ ... });
});
afterEach(function() {
vol.reset();
});
it('should do something with the sut', async function() {
const result = await sut.doSomething(); // Even works if the sut imported 'fs/promises' like every sane person does
expect(result).to.be.something.really.nice;
});
});
Activity
zbigg commentedon Dec 22, 2023
For anyone trying to fix it, it's caused by node20 to use new binding method:
readFileUtf8which isn't "mocked" by this module.It looks like we should just implement open+read+toUtf+close as one function here.
The usage:
https://github.com/nodejs/node/blob/a81788cb27b96579343765eeba07fd2b772829d0/lib/fs.js#L456
Implementation
https://github.com/nodejs/node/blob/a81788cb27b96579343765eeba07fd2b772829d0/src/node_file.cc#L2375
This is very naive and PoC binding that fixes
readFileSync(..., 'utf8')for node 20canhassancode commentedon Dec 22, 2023
Facing the exact same issue, it was working completely fine then randomly broke. Below is an example of the setup:
Getting the error:
ENOENT: no such file or directory, open 'profiles/test/TEST_PROFILE_2.json'crfrolik commentedon Jan 30, 2024
For those like me who came here in a panic because their tests started failing, I had success (and minimal effort) replacing
mock-fswithmemfs.PedroS11 commentedon Feb 6, 2024
Do you mind post some examples please? I'm trying to use memfs but I'm struggling with it. I found an basic example with jest however, i'm using chai so nothing is working
For reference, this is the basic example of
memfsusing jest: https://medium.com/nerd-for-tech/testing-in-node-js-easy-way-to-mock-filesystem-883b9f822ea4or https://dev.to/julienp/node-js-testing-using-a-virtual-filesystem-as-a-mock-2jln
JBloss1517 commentedon Feb 24, 2024
@PedroS11 I also decided to switch using memfs. For me, it was mostly a matter of switching
mockFS({. . .})withvol.fromNestedJSON({. . .})and changingmockFS.restore()tovol.reset()So for example (I am using vitest in this but jest should be pretty close as well)
Using mock-fs
Using memfs
I hope that helps!
PedroS11 commentedon Feb 24, 2024
Thank you for this snippet @JBloss1517 !! in the following weeks, I'll try to migrate too and I'll see how it works. I'll leave my progress here when I start so it helps everyone with this struggle
launch tests with the updated Node.js images
launch tests with the updated Node.js images
launch tests with the updated Node.js images
launch tests with the updated Node.js images
launch tests with the updated Node.js images
dennismeister93 commentedon Mar 10, 2024
hi @tschaub, are there any plans to work on this?
tschaub commentedon Mar 18, 2024
@dennismeister93 - I would be happy to review a pull request, but don't have plans to spend time on a fix myself.
dicolasi commentedon Apr 16, 2024
struggling with the same problem here.
MichaelSitter commentedon May 7, 2024
I was having issues with my Jest tests still using the built-in fs instead of the memfs implementation. This worked to mock out fs & fs/promises:
bcass commentedon Jun 17, 2024
Here's an example of migrating a mock-fs test that used
mock.load()to memfs. The test itself doesn't change. Just adding avi.mock()and changing thebeforeEach()andafterEach().Before with mock-fs:
After with memfs:
sketchbuch commentedon Jul 20, 2024
What is the mocha equiv. of jest.mock?
BadIdeaException commentedon Jul 24, 2024
In mocha there is a little more work required, because it does not include a mocking system of its own. Usually you use the excellent Sinon for mocking, but in this special case this won't work since, by specification, imports must be unalterable. Instead, I use esmock to mock out modules. Something like this works for me:
Switched tests from mock-fs to memfs.
test: use memfs for jest tests for node 20 compatibility
replace mock-fs as it does not support node20
TheJaredWilcurt commentedon Mar 16, 2026
Note for my future self. Mocking writeFileSync with memfs and vitest.
SEO:
vitest mock writefilesync memfs
vitest force writing to filesystem to fail