Last active
February 25, 2023 23:20
-
-
Save barthap/e0a672e9000e72cdfbca73e4f2702f5e to your computer and use it in GitHub Desktop.
Mocking filesystem in Node.js with `memfs`
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// __mocks__/fs/promises.js | |
const { fs } = require("memfs"); | |
module.exports = fs.promises; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// __mocks__/fs.js | |
const { fs } = require("memfs"); | |
module.exports = fs; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// src/__tests__/checkHello.test.js | |
// fs-extra is used for demonstrational purposes | |
const fs = require("fs-extra"); | |
const { vol } = require("memfs"); | |
// mock `fs` if you use either `fs` or `fs-extra` | |
jest.mock("fs"); | |
// mock `fs/promises` if you use it either in code or tests | |
jest.mock("fs/promises"); | |
const { checkHelloAsync, checkHelloExtra } = require("../checkHello"); | |
describe(checkHelloAsync, () => { | |
beforeEach(() => { | |
// we reset virtual filesystem before each test | |
vol.reset(); | |
}); | |
it("should return true if file starts with hello", async () => { | |
const filePath = "/file.txt"; | |
//we save file in virtual filesystem | |
await fs.writeFile(filePath, "hello Test"); | |
/** | |
* You can swap lines below for different implementation | |
* and this test will work anyway | |
*/ | |
// const result = await checkHelloExtra(filePath) | |
const result = await checkHelloAsync(filePath); | |
expect(result).toBe(true); | |
}); | |
it("tests checkHelloAsync on multiple files", async () => { | |
vol.fromJSON( | |
{ | |
"./some/file1.txt": "hello world", | |
"./other/file2.txt": "h3ll0 w0rld", | |
}, | |
"/tmp" // cwd (current working directory) | |
); | |
await expect(checkHelloAsync("/tmp/some/file1.txt")).resolves.toBe(true); | |
await expect(checkHelloAsync("/tmp/other/file2.txt")).resolves.toBe(false); | |
}); | |
}); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// src/checkHello.js | |
const fs = require("fs"); | |
const fsPromises = require("fs/promises"); | |
const fsExtra = require("fs-extra"); | |
// using fs sync calls | |
function checkHelloSync(filePath) { | |
const fd = fs.openSync(filePath); | |
const content = Buffer.alloc(5); | |
const bytesRead = fs.readSync(fd, content, 0, 5, 0); | |
fs.closeSync(fd); | |
if (bytesRead !== 5) return false; | |
return content.toString() === "hello"; | |
} | |
// using fsPromises | |
async function checkHelloAsync(filePath) { | |
const fd = await fsPromises.open(filePath, "r"); | |
const { buffer, bytesRead } = await fd.read(Buffer.alloc(5), 0, 5, 0); | |
await fd.close(); | |
return bytesRead === 5 && buffer.toString("utf8") === "hello"; | |
} | |
// using fs-extra | |
async function checkHelloExtra(filePath) { | |
const fd = await fsExtra.open(filePath, "r"); | |
const { buffer, bytesRead } = await fsExtra.read( | |
fd, | |
Buffer.alloc(5), | |
0, 5, 0 | |
); | |
await fs.close(fd); | |
return bytesRead === 5 && buffer.toString("utf8") === "hello"; | |
} | |
module.exports = { | |
checkHelloSync, | |
checkHelloAsync, | |
checkHelloExtra, | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hello ☀️
I tried to test a simple function using
fs-extra
withmemfs
but the test fails, and the function called in the test is not aware of the in-memory fs.I posted a question on stackoverflow. Could you help me with making this work, please ?