diff --git a/CHANGELOG.md b/CHANGELOG.md index c1fb4bc7ae42..d84c581f30c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,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)) diff --git a/docs/MockFunctionAPI.md b/docs/MockFunctionAPI.md index b77e9a27d856..fab938c6835c 100644 --- a/docs/MockFunctionAPI.md +++ b/docs/MockFunctionAPI.md @@ -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. diff --git a/packages/jest-mock/src/__tests__/index.test.ts b/packages/jest-mock/src/__tests__/index.test.ts index 5bfbbd877223..27b13b594c18 100644 --- a/packages/jest-mock/src/__tests__/index.test.ts +++ b/packages/jest-mock/src/__tests__/index.test.ts @@ -1215,6 +1215,30 @@ describe('moduleMocker', () => { expect(fn.getMockName()).toBe('jest.fn()'); }); + test('after mock reset, the object should return to its original value', () => { + const myObject = {bar: () => 'bar'}; + + const barStub = moduleMocker.spyOn(myObject, 'bar'); + + barStub.mockReturnValue('POTATO!'); + expect(myObject.bar()).toBe('POTATO!'); + barStub.mockReset(); + + expect(myObject.bar()).toBe('bar'); + }); + + test('after resetAllMocks, the object should return to its original value', () => { + const myObject = {bar: () => 'bar'}; + + const barStub = moduleMocker.spyOn(myObject, 'bar'); + + barStub.mockReturnValue('POTATO!'); + expect(myObject.bar()).toBe('POTATO!'); + moduleMocker.resetAllMocks(); + + expect(myObject.bar()).toBe('bar'); + }); + test('mockName gets reset by mockRestore', () => { const fn = jest.fn(); expect(fn.getMockName()).toBe('jest.fn()'); diff --git a/packages/jest-mock/src/index.ts b/packages/jest-mock/src/index.ts index f143564bf733..5ff1ca67dade 100644 --- a/packages/jest-mock/src/index.ts +++ b/packages/jest-mock/src/index.ts @@ -509,6 +509,7 @@ export class ModuleMocker { private _mockConfigRegistry: WeakMap; private _spyState: Set<() => void>; private _invocationCallCounter: number; + private _originalFn: WeakMap; /** * @see README.md @@ -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): Array { @@ -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; }; @@ -1215,7 +1222,7 @@ export class ModuleMocker { return original.apply(this, arguments); }); } - + this._originalFn.set(object[methodKey] as Mock, original); return object[methodKey] as Mock; } @@ -1401,6 +1408,7 @@ export class ModuleMocker { } resetAllMocks(): void { + this._spyState.forEach(reset => reset()); this._mockConfigRegistry = new WeakMap(); this._mockState = new WeakMap(); }