I am trying to mock the promise
version of fs.writeFile
using Jest, and the mocked function is not being called.
Function to be tested (createFile.js)
:
const { writeFile } = require("fs").promises;
const createNewFile = async () => {
await writeFile(`${__dirname}/newFile.txt`, "Test content");
};
module.exports = {
createNewFile,
};
Jest Test (createFile.test.js
):
const fs = require("fs").promises;
const { createNewFile } = require("./createFile.js");
it("Calls writeFile", async () => {
const writeFileSpy = jest.spyOn(fs, "writeFile");
await createNewFile();
expect(writeFileSpy).toHaveBeenCalledTimes(1);
writeFileSpy.mockClear();
});
I know that writeFile
is actually being called because I ran node -e "require(\"./createFile.js\").createNewFile()"
and the file was created.
Dependency Versions
-- Here is another attempt at the createFile.test.js
file --
const fs = require("fs");
const { createNewFile } = require("./createFile.js");
it("Calls writeFile", async () => {
const writeFileMock = jest.fn();
jest.mock("fs", () => ({
promises: {
writeFile: writeFileMock,
},
}));
await createNewFile();
expect(writeFileMock).toHaveBeenCalledTimes(1);
});
This throws the following error:
ReferenceError: /Users/danlevy/Desktop/test/src/createFile.test.js: The module factory of `jest.mock()` is not allowed to reference any out-of-scope variables.
Invalid variable access: writeFileMock
Since writeFile
is destructured at import time instead of being consistently referred as fs.promises.writeFile
method, it cannot be affected with spyOn
.
It should be mocked as any other module:
jest.mock("fs", () => ({
promises: {
writeFile: jest.fn().mockResolvedValue(),
readFile: jest.fn().mockResolvedValue(),
},
}));
const fs = require("fs");
...
await createNewFile();
expect(fs.promises.writeFile).toHaveBeenCalledTimes(1);
It make sense to mock fs
scarcely because unmocked functions provide side effects and potentially have negative impact on test environment.