Skip to content

Commit

Permalink
Add "restoreAllMocks" to the API. Closes #3580 (#4045)
Browse files Browse the repository at this point in the history
  • Loading branch information
mjesun authored and aaronabramov committed Jul 17, 2017
1 parent 2f7c373 commit a5a8a13
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 1 deletion.
6 changes: 5 additions & 1 deletion docs/en/JestObjectAPI.md
Expand Up @@ -24,6 +24,7 @@ The `jest` object is automatically in scope within every test file. The methods
- [`jest.dontMock(moduleName)`](#jestdontmockmodulename)
- [`jest.clearAllMocks()`](#jestclearallmocks)
- [`jest.resetAllMocks()`](#jestresetallmocks)
- [`jest.restoreAllMocks()`](#jestrestoreallmocks)
- [`jest.resetModules()`](#jestresetmodules)
- [`jest.runAllTicks()`](#jestrunallticks)
- [`jest.runAllTimers()`](#jestrunalltimers)
Expand Down Expand Up @@ -179,8 +180,11 @@ Resets the state of all mocks. Equivalent to calling `.mockReset()` on every moc

Returns the `jest` object for chaining.

### `jest.resetModules()`
### `jest.restoreAllMocks()`
##### available in Jest **20.1.0+**
Restores all mocks back to their original value. Equivalent to calling `.mockRestore` on every mocked function. Beware that `jest.restoreAllMocks()` only works when mock was created with `jest.spyOn`; other mocks will require you to manually restore them.

### `jest.resetModules()`
Resets the module registry - the cache of all required modules. This is useful to isolate modules where local state might conflict between tests.

Example:
Expand Down
36 changes: 36 additions & 0 deletions packages/jest-mock/src/__tests__/jest_mock.test.js
Expand Up @@ -488,5 +488,41 @@ describe('moduleMocker', () => {
moduleMocker.spyOn({method: 10}, 'method');
}).toThrow();
});

it('supports restoring all spies', () => {
let methodOneCalls = 0;
let methodTwoCalls = 0;
const obj = {
methodOne() {
methodOneCalls++;
},
methodTwo() {
methodTwoCalls++;
},
};

const spy1 = moduleMocker.spyOn(obj, 'methodOne');
const spy2 = moduleMocker.spyOn(obj, 'methodTwo');

// First, we call with the spies: both spies and both original functions
// should be called.
obj.methodOne();
obj.methodTwo();
expect(methodOneCalls).toBe(1);
expect(methodTwoCalls).toBe(1);
expect(spy1.mock.calls.length).toBe(1);
expect(spy2.mock.calls.length).toBe(1);

moduleMocker.restoreAllMocks();

// Then, after resetting all mocks, we call methods again. Only the real
// methods should bump their count, not the spies.
obj.methodOne();
obj.methodTwo();
expect(methodOneCalls).toBe(2);
expect(methodTwoCalls).toBe(2);
expect(spy1.mock.calls.length).toBe(1);
expect(spy2.mock.calls.length).toBe(1);
});
});
});
12 changes: 12 additions & 0 deletions packages/jest-mock/src/index.js
Expand Up @@ -165,6 +165,7 @@ class ModuleMockerClass {
_environmentGlobal: Global;
_mockState: WeakMap<Function, MockFunctionState>;
_mockConfigRegistry: WeakMap<Function, MockFunctionConfig>;
_spyState: Set<() => void>;
ModuleMocker: Class<ModuleMockerClass>;

/**
Expand All @@ -176,6 +177,7 @@ class ModuleMockerClass {
this._environmentGlobal = global;
this._mockState = new WeakMap();
this._mockConfigRegistry = new WeakMap();
this._spyState = new Set();
this.ModuleMocker = ModuleMockerClass;
}

Expand Down Expand Up @@ -302,6 +304,10 @@ class ModuleMockerClass {
f._isMockFunction = true;
f.getMockImplementation = () => this._ensureMockConfig(f).mockImpl;

if (typeof restore === 'function') {
this._spyState.add(restore);
}

this._mockState.set(f, this._defaultMockState());
this._mockConfigRegistry.set(f, this._defaultMockConfig());

Expand Down Expand Up @@ -579,6 +585,7 @@ class ModuleMockerClass {
object[methodName] = this._makeComponent({type: 'function'}, () => {
object[methodName] = original;
});

object[methodName].mockImplementation(function() {
return original.apply(this, arguments);
});
Expand All @@ -595,6 +602,11 @@ class ModuleMockerClass {
this._mockConfigRegistry = new WeakMap();
this._mockState = new WeakMap();
}

restoreAllMocks() {
this._spyState.forEach(restore => restore());
this._spyState = new Set();
}
}

export type ModuleMocker = ModuleMockerClass;
Expand Down
4 changes: 4 additions & 0 deletions packages/jest-runtime/src/index.js
Expand Up @@ -462,6 +462,10 @@ class Runtime {
this._mockFactories[moduleID] = mockFactory;
}

restoreAllMocks() {
this._moduleMocker.restoreAllMocks();
}

resetAllMocks() {
this._moduleMocker.resetAllMocks();
}
Expand Down

0 comments on commit a5a8a13

Please sign in to comment.