Reputation: 2673
I've mocked some nodejs modules (one of them, for example, is fs
). I have them in a __mocks__
folder (same level als node_modules
) folder and the module mocking works. However, whichever "between test clearing" option I use, the next test is not "sandboxed". What is going wrong here?
A very simplified example of the mocked fs
module is:
// __mocks__/fs.js
module.exports = {
existsSync: jest.fn()
.mockReturnValueOnce(1)
.mockReturnValueOnce(2)
.mockReturnValueOnce(3)
}
I'm simply expecting that in every test, whenever init()
is called (see below), existsSync
starts again at value 1: the first value of jest.fn().mockReturnValue()
. In the testfile I have the following structure:
// init.test.js
const init = require("../init");
const { existsSync } = require("fs");
jest.mock("fs");
describe("initializes script", () => {
afterEach(() => {
// see below!
});
test("it checks for a package.json in current directory", () => {
init();
});
test("it stops script if there's a package.json in dir", () => {
init(); // should be run in clean environment!
});
}
And once again very simplified, the init.js file
const { existsSync } = require("fs");
console.log("value of mocked response : ", existsSync())
I'm getting the following results for existsSync()
after the first and second run ofinit()
respectively when I run in afterEach()
:
1
, 2
1
, undefined
1
, 2
1
, undefined
Somebody know what I'am doing wrong? How do I clear module mock between tests in the same suite? I'll glady clarify if necessary. Thanks!
Upvotes: 13
Views: 16523
Reputation: 4545
For local variables, the scope of declaration is important.
const mockFunc1 = jest.fn() // possibly bad mock reset/clear between tests
describe('useGetMetaData', () => {
const mockFunc2 = jest.fn() // good mock reset/clear between tests
afterEach(() => {/* reset/clear mocks */})
test.todo('implement tests here')
})
Upvotes: -1
Reputation: 321
I had problems with the solution above. I managed to solve the issue with the next snippet.
afterEach(() => {
Object.keys(mockedModule).forEach(method => mockedModule[method].mockReset())
})
I would prefer to have a native method doing this though. Something like mockedModule.mockReset()
.
Upvotes: 0
Reputation: 1616
Reset the modules and require them again for each test:
describe("initializes script", () => {
afterEach(() => {
jest.resetModules()
});
beforeEach(() => {
jest.mock("fs");
})
test("it checks for a package.json in current directory", () => {
const init = require("../init");
init();
});
test("it stops script if there's a package.json in dir", () => {
const init = require("../init");
init();
});
}
Upvotes: 15