Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: jest.restoreAllMocks(); breaks global mock #13969

Closed
akaNightmare opened this issue Feb 28, 2023 · 5 comments
Closed

[Bug]: jest.restoreAllMocks(); breaks global mock #13969

akaNightmare opened this issue Feb 28, 2023 · 5 comments

Comments

@akaNightmare
Copy link

akaNightmare commented Feb 28, 2023

Version

29.4.3

Steps to reproduce

const client = {
    getConfigurationItems: jest.fn().mockImplementation(async () => [1, 2, 3, 4]),
};
jest.mock('@package/some-lib', () => ({
    ...jest.requireActual('@package/some-lib'),
    getClient: jest.fn().mockImplementation(() => client),
}));

import someLib from '@package/some-lib';

describe('Describe', () => {
  afterEach(() => {
    jest.restoreAllMocks(); // If comment this line everything is working as expected
  });

  it('test1', () => {
    const client = someLib.getClient();
    await client.getConfigurationItems();
    expect(someLib.getClient).toHaveBeenCalled(); // Passed for the first time
  });

  it('test2', () => {
    const client = someLib.getClient();
    await client.getConfigurationItems();
    expect(someLib.getClient).toHaveBeenCalled(); // Failed
  });
});

Expected behavior

I expect to see passed tests as expected. It works for jest 28v

Actual behavior

See error

Error: expect(jest.fn()).toHaveBeenCalled()

Expected number of calls: >= 1
Received number of calls:    0

Additional context

No response

Environment

System:
    OS: macOS 13.0
    CPU: (10) arm64 Apple M1 Pro
  Binaries:
    Node: 18.14.2 - ~/.nvm/versions/node/v18.14.2/bin/node
    npm: 9.5.0 - ~/.nvm/versions/node/v18.14.2/bin/npm
  npmPackages:
    jest: ^29.4.3 => 29.4.3
@mrazauskas
Copy link
Contributor

Instead of using afterEach you can write your tests like this:

describe('Describe', () => {
  it('test1', () => {
    const client = someLib.getClient();
    await client.getConfigurationItems();
    expect(someLib.getClient).toHaveBeenCalled(); // Passed for the first time

    someLib.getClient.mockRestore();
    client.getConfigurationItems.mockRestore();
  });

  it('test2', () => {
    const client = someLib.getClient();
    await client.getConfigurationItems();
    expect(someLib.getClient).toHaveBeenCalled(); // Failed

    someLib.getClient.mockRestore();
    client.getConfigurationItems.mockRestore();
  });
});

If any of the tests will run alone, it will pass; otherwise second test fails. This is because .mockRestore() will reset and clear your mocks. jest.restoreAllMocks() had a bug before.

@akaNightmare
Copy link
Author

I know, but what if I have a tons of mocks? I assume it is not very convenient to do such manipulations every time.
Is it expected behaviour?

@mrazauskas
Copy link
Contributor

Sorry if that was not clear. I was trying to say that:

afterEach(() => {
  jest.restoreAllMocks();
});

Is equivalent to what I was showing in the above example.

The idea is that the above example will fail on Jest 28, just like jest.restoreAllMocks() is failing your tests after upgrading Jest. jest.restoreAllMocks() had a bug for long time, it did not restore mocks. I guess all what you need is jest.clearAllMocks().

@akaNightmare
Copy link
Author

@mrazauskas Thank you, it works. Now need to refactor all the code and replace restoreAllMocks with clearAllMocks where it's needed (:

@github-actions
Copy link

github-actions bot commented Apr 1, 2023

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 1, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants