jest icon indicating copy to clipboard operation
jest copied to clipboard

jest.resetAllMocks also resets manual mocks

Open nilsm opened this issue 5 years ago • 7 comments

🐛 Bug Report

Calling jest.resetAllMocks() resets manual mocks created via a _ _ mocks _ _ folder. I'm calling this a bug because it means there is no way to return to the original, manually mocked implementation. The manual mock is wiped out by resetAllMocks(); It also means that you can't easily mix and match manual mocks and the mockResolvedValue, mockValue, mockImplementation, etc. methods.

To Reproduce

Use a manual mock, and call jest.resetAllMocks()

Expected behavior

I expect the manual mock to be restored to its manually mocked state, and not to a blank mock.

Link to repl or repo (highly encouraged)

I couldn't create a _ _ mocks _ _ folder in repl.it, can upload a repo later if required.

envinfo

System:
    OS: macOS 10.15.5
    CPU: (4) x64 Intel(R) Core(TM) i5-5287U CPU @ 2.90GHz
  Binaries:
    Node: 12.18.1 - ~/.nvm/versions/node/v12.18.1/bin/node
    npm: 6.14.7 - ~/.nvm/versions/node/v12.18.1/bin/npm
  npmPackages:
    jest: ^26.2.2 => 26.3.0 

nilsm avatar Aug 17 '20 11:08 nilsm

Your sentence "there is no way to return to the original, manually mocked implementation" sums it all. I've spent hours playing with clearAllMocks, resetAllMocks, restoreAllMocks, resetModules trying to find a clean solution. There are none.

In my opinion this is what you would expect from restoreAllMocks instead of "only works when the mock was created with jest.spyOn".

What's the point of having __mocks__ if restoreAllMocks does not use it?

// __mocks__/npm-package.js

export const foo = jest.fn(() => 'original');
// mytest.test.js

import { foo } from 'npm-package';

//beforeEach(jest.restoreAllMocks);

test('original', () => {
  expect(foo()).toEqual('original');
});

test('override', () => {
  foo.mockReturnValue('override');
  expect(foo()).toEqual('override');
});

test('original', () => {
  jest.restoreAllMocks();
  // FAIL
  // restoreAllMocks/resetAllMocks assigns jest.fn() to foo instead of using __mocks__/npm-package.js
  expect(foo()).toEqual('original');
});

Related:

  • https://stackoverflow.com/questions/49494744/how-to-reset-manual-mocks-in-jest
  • https://github.com/facebook/jest/issues/5969#issuecomment-400161210
  • https://github.com/facebook/jest/issues/7068
  • https://stackoverflow.com/a/59792748

tkrotoff avatar Nov 20 '20 13:11 tkrotoff

I agree with this sentiment. I could definitely use a way to reset back to the original mock. In my case I'm trying to mock the knex module. Currently I'm doing the following:

// __mocks__/knex.js
export default {
    select: jest.fn().mockReturnThis(),
    from: jest.fn().mockReturnThis(),
    where: jest.fn().mockReturnThis(),
    whereNotNull: jest.fn().mockReturnThis(),
    del: jest.fn().mockReturnThis(),
    insert: jest.fn().mockReturnThis(),
    into: jest.fn().mockReturnThis(),
    orderBy: jest.fn().mockReturnThis(),
    limit: jest.fn().mockReturnThis(),
    first: jest.fn().mockReturnThis(),
    then: jest.fn(function (done) {
        done(null)
    })
}

When i override one of the properties to provide a specific value for my test I then cant reset it back to the original mock as iv lost the context of this.

ccmattr avatar Jun 10 '21 13:06 ccmattr

see also https://github.com/facebook/jest/issues/7573 that's similar. Still no answer to this issue, I bumped into it again today :/

julienw avatar Jul 25 '22 13:07 julienw

I just wasted hours trying to figure out why my __mocks__ weren't working... Turns out it was resetMocks: true in my jest.config.js...

Why would you ever want to reset manual mocks to essentially be an empty jest.fn()? I would expect resetting a manual mock would set it back to the state defined in the __mocks__ module.

Also, this only seems to apply to manual mocks of user modules. Manual mocks of node modules seem to work fine with resetMocks: true in my Jest config... 🙃

adambiggs avatar Jul 29 '22 23:07 adambiggs

Just ran into this today. I can't find any function that would reset jest.spyOn, but restore the original manual __mocks__. It always just returns to default jest.fn().

I can work around by ordering the tests differently (yuck). This is just nasty.

MilanJimi avatar Feb 16 '23 12:02 MilanJimi

This issue is stale because it has been open for 1 year with no activity. Remove stale label or comment or this will be closed in 30 days.

github-actions[bot] avatar Feb 16 '24 13:02 github-actions[bot]

Please don't close 🙏 (I hate those bots)

tkrotoff avatar Feb 16 '24 14:02 tkrotoff