axm__
axm__

Reputation: 2673

How to clear a module mock between tests in same test suite in Jest?

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():

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

Answers (3)

piouson
piouson

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

fabioDMFerreira
fabioDMFerreira

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

Alexandre Borela
Alexandre Borela

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

Related Questions