For some reason, using mock-fs in beforeEach() hooks causes all calls to console.log in it() functions to throw a ENOENT, no such file or directory '/path/to/project/node_modules/callsites' error.
const mock = require("mock-fs");
describe("tests", () => {
beforeEach(() => {
mock({
"/foo/bar": {}
});
});
afterEach(() => {
mock.restore();
});
it("should fail", () => {
console.log(`This console.log will cause an error`);
});
});
envinfo:
System:
OS: macOS Sierra 10.12.6
CPU: x64 Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz
Binaries:
Node: 8.4.0
Yarn: 1.3.2
npm: 5.6.0
npmPackages:
jest:
wanted: ^22.4.2
installed: 22.4.2
Reproduction repo: https://github.com/AriaMinaei/jest-mock-fs-bug
I'll try to shed some light on this issue.
callsites is used in the buffered console under the write method, to understand the origin of the log and provide a better experience.
This method is used here:
https://github.com/facebook/jest/blob/124067e7d662364d40fc662ef54bfddd798c57c4/packages/jest-runner/src/run_test.js#L85
seems that the error comes from mock-fs, from here. Which indicates that this import to callsites is actually taken cared by the mocked fs and not by the real one.
The runTest function is imported from the test_worker which means it has the same context as the test itself (and mock-fs's).
There is a similar issue in mock-fs repo.
I'm not sure what is the wanted behavior here, but using this example should work fine.
To add more, if mock() from mock-fs is called inside the it() block, everything works fine. The error only happens if mock() is called in the beforeEach() block.
Seems to me that calling console.log just before calling mock-fs is a workaround. https://github.com/nknapp/jest-mock-fs-bug
I've started on support for an overlay option for mock-fs. This should fix the lazy require issue. In the meantime, @nknapp's workaround is an alternative (calling console.log() before mocking the filesystem).
Possible workaround
const fsMock = require('mock-fs')
let logsTemp = []
let logMock
exports.mock = (config) => {
logMock = jest.spyOn(console, 'log').mockImplementation((...args) => {
logsTemp.push(args)
})
fsMock(config)
}
exports.restore = () => {
logMock.mockRestore()
fsMock.restore()
logsTemp.map(el => console.log(...el))
logsTemp = []
}
Does it happen with jest@beta?
happends on most recent jest@24
Most helpful comment
Seems to me that calling
console.logjust before callingmock-fsis a workaround. https://github.com/nknapp/jest-mock-fs-bug