最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to clear a module mock between tests in same test suite in Jest? - Stack Overflow

programmeradmin3浏览0评论

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

  • jest.resetModules() : 1, 2
  • existsSync.mockReset(): 1, undefined
  • existsSync.mockClear(): 1, 2
  • existsSync.mockRestore(): 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!

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

  • jest.resetModules() : 1, 2
  • existsSync.mockReset(): 1, undefined
  • existsSync.mockClear(): 1, 2
  • existsSync.mockRestore(): 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!

Share Improve this question edited Nov 3, 2018 at 10:38 skyboyer 23.7k7 gold badges61 silver badges71 bronze badges asked Sep 28, 2018 at 18:50 axm__axm__ 2,6732 gold badges22 silver badges37 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 15

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();
    });
}

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

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')
})
发布评论

评论列表(0)

  1. 暂无评论