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

fix: stop changing the behaviour of spies on mockFn.mockReset #13692

Merged
merged 11 commits into from Jan 6, 2023
Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -13,6 +13,7 @@

- `[jest-environment-node]` fix non-configurable globals ([#13687](https://github.com/facebook/jest/pull/13687))
- `[@jest/expect-utils]` `toMatchObject` should handle `Symbol` properties ([#13639](https://github.com/facebook/jest/pull/13639))
- `[jest-mock]` fix mockReset and resetAllMocks undefined return ([#13692](https://github.com/facebook/jest/pull/13692))
- `[jest-resolve]` Add global paths to `require.resolve.paths` ([#13633](https://github.com/facebook/jest/pull/13633))
- `[jest-runtime]` Support Wasm files that import JS resources ([#13608](https://github.com/facebook/jest/pull/13608))
- `[jest-snapshot]` Make sure to import `babel` outside of the sandbox ([#13694](https://github.com/facebook/jest/pull/13694))
Expand Down
2 changes: 1 addition & 1 deletion docs/MockFunctionAPI.md
Expand Up @@ -126,7 +126,7 @@ The [`clearMocks`](configuration#clearmocks-boolean) configuration option is ava

Does everything that [`mockFn.mockClear()`](#mockfnmockclear) does, and also removes any mocked return values or implementations.

This is useful when you want to completely reset a _mock_ back to its initial state. (Note that resetting a _spy_ will result in a function with no return value).
This is useful when you want to completely reset a _mock_ back to its initial state.

The [`resetMocks`](configuration#resetmocks-boolean) configuration option is available to reset mocks automatically before each test.

Expand Down
46 changes: 46 additions & 0 deletions e2e/mock-reset/__tests__/index.test.js
@@ -0,0 +1,46 @@
/**
feliperli marked this conversation as resolved.
Show resolved Hide resolved
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

describe('with mock reset', () => {
const myObject = {bar: () => 'bar'};

let barStub;

beforeAll(() => {
barStub = jest.spyOn(myObject, 'bar');
});

test('after mock reset, bar should return to its original value', () => {
barStub.mockReturnValue('POTATO!');
expect(myObject.bar()).toBe('POTATO!');
barStub.mockReset();

// This expect should be successful
expect(myObject.bar()).toBe('bar');
});
});

describe('with reset all mocks', () => {
const myObject = {bar: () => 'bar', foo: () => 'foo'};

let barStub;

beforeAll(() => {
barStub = jest.spyOn(myObject, 'bar');
});

test('after reset all, bar should return to its original value', () => {
barStub.mockReturnValue('POTATO!');
expect(myObject.bar()).toBe('POTATO!');
jest.resetAllMocks();

// This expect should be successful
expect(myObject.bar()).toBe('bar');
});
});
5 changes: 5 additions & 0 deletions e2e/mock-reset/package.json
@@ -0,0 +1,5 @@
{
"jest": {
"testEnvironment": "node"
}
}
12 changes: 10 additions & 2 deletions packages/jest-mock/src/index.ts
Expand Up @@ -509,6 +509,7 @@ export class ModuleMocker {
private _mockConfigRegistry: WeakMap<Function, MockFunctionConfig>;
private _spyState: Set<() => void>;
private _invocationCallCounter: number;
private _originalFn: WeakMap<Mock, Function>;

/**
* @see README.md
Expand All @@ -521,6 +522,7 @@ export class ModuleMocker {
this._mockConfigRegistry = new WeakMap();
this._spyState = new Set();
this._invocationCallCounter = 1;
this._originalFn = new WeakMap();
}

private _getSlots(object?: Record<string, any>): Array<string> {
Expand Down Expand Up @@ -775,7 +777,12 @@ export class ModuleMocker {

f.mockReset = () => {
f.mockClear();
this._mockConfigRegistry.delete(f);
const originalFn = this._originalFn.get(f);
const originalMockImpl = {
...this._defaultMockConfig(),
mockImpl: originalFn,
};
this._mockConfigRegistry.set(f, originalMockImpl);
return f;
};

Expand Down Expand Up @@ -1215,7 +1222,7 @@ export class ModuleMocker {
return original.apply(this, arguments);
});
}

this._originalFn.set(object[methodKey], original);
return object[methodKey] as Mock;
}

Expand Down Expand Up @@ -1401,6 +1408,7 @@ export class ModuleMocker {
}

resetAllMocks(): void {
this._spyState.forEach(reset => reset());
this._mockConfigRegistry = new WeakMap();
this._mockState = new WeakMap();
}
Expand Down