question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Proposal: Revert override of jest default `resetMocks`

See original GitHub issue

About

Hey what’s up!

I found myself trying to work out why all my tests broke when upgrading react-scripts and then realized it’s because of the change to enabling resetMocks by default.

I wanted to challenge this decision because, especially when react-scripts is targeted at newer users looking to use react, this causes fundamental jest examples online to break.

App-wide mocks

It also means app-wide mocks such as these don’t work.

// some-mocked-module.js
export const useSomeHook = jest.fn(() => true);
// setupTests.js
jest.mock('some-mocked-module', () => ({
  useSomeHook: jest.fn(() => true)
}))

For new users, I can see why it would be very confusing.

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:83
  • Comments:15 (3 by maintainers)

github_iconTop GitHub Comments

28reactions
kentcdoddscommented, Nov 25, 2020

Resetting a mock will reset it’s mock implementation, this could make it confusing if you tried to do this:

beforeAll(() => {
  const originalError = console.error
  jest.spyOn(console, 'error')
  console.error.mockImplementation((...args) => {
    if (args?.[0]?.includes('something to ignore')) return
    originalError(...args)
  })
})

With resetMocks that mock implementation will only work for the first test, then it will get reset. The fix for this would be to require folks to do this:

beforeAll(() => {
  const originalError = console.error
  jest.spyOn(console, 'error')
})

beforeEach(() => {
  console.error.mockImplementation((...args) => {
    if (args?.[0]?.includes('something to ignore')) return
    originalError(...args)
  })
})

That works, but it can be confusing.

However, there are great reasons to get the mocks cleared between runs. So I think I’d suggest using clearMocks: true instead of resetMocks: true. The only big difference is that the mock implementation remains. This comes with its own set of trade-offs though because it means that if I do this:

beforeAll(() => {
  const originalError = console.error
  jest.spyOn(console, 'error')
})

test('some test thing', () => {
  console.error.mockImplementation((...args) => {
    if (args?.[0]?.includes('something to ignore')) return
    originalError(...args)
  })
})

test('some other test thing', () => {
  // with resetMocks, calling console.error will call the underlying console.error always
  // with clearMocks, calling console.error will call the mock implementation in the previous test 😬
})

With that context, I’m not certain which to suggest. I think resetMocks is probably the best between the two, but there are foot guns for both.

Last thing I’d say is that we should configure at least one of them. You never want to have the mock state preserved between tests. So it should at least do clearMocks.

19reactions
lithammercommented, Nov 24, 2020

@k-yle Are you sure? Adding this to package.json solved it for us using CRA 4.0.1:

  "jest": {
    "resetMocks": false
  }
Read more comments on GitHub >

github_iconTop Results From Across the Web

Mocks broken after updating to Jest 26 - Stack Overflow
Jest 26 changed the default behavior of resetMocks to true, which resets mock state before each test. You can revert to the prior...
Read more >
How to automatically reset mocks and restore spies in Jest
Configuring Jest to automatically reset / restore mocks and spies · “clearMocks”: true : resets all the mocks usage data, but keeps the...
Read more >
Jest CLI Options
Run all tests (default): ... jest --watch #runs jest -o by default ... Optionally pass <boolean> to override option set in configuration.
Read more >
Updating React to version 17 - Medium
react-scripts jest config has a breaking change: resetMocks is true by default and also causes mocks to reset in nested describe . To...
Read more >
Jest-fetch-mock: Jest Mock for Fetch - Morioh
resetMocks () will return to the default behavior of mocking all fetches with a text response of empty string. fetch.dontMock() - Change the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found