Skip to content
/ jest Public
forked from jestjs/jest

Commit 66fb417

Browse files
authored
fix(jest-mock): clear mock when jest.restoreAllMocks() is called (jestjs#13867)
1 parent ca8acf7 commit 66fb417

File tree

3 files changed

+114
-19
lines changed

3 files changed

+114
-19
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
### Fixes
66

7+
- `[jest-mock]` Clear mock state when `jest.restoreAllMocks()` is called ([#13867](https://github.com/facebook/jest/pull/13867))
8+
79
### Chore & Maintenance
810

911
### Performance

packages/jest-mock/src/__tests__/index.test.ts

+111-19
Original file line numberDiff line numberDiff line change
@@ -1312,6 +1312,36 @@ describe('moduleMocker', () => {
13121312
);
13131313
});
13141314

1315+
it('supports restoring a spy', () => {
1316+
let methodOneCalls = 0;
1317+
const obj = {
1318+
methodOne() {
1319+
methodOneCalls++;
1320+
},
1321+
};
1322+
1323+
const spy1 = moduleMocker.spyOn(obj, 'methodOne');
1324+
1325+
obj.methodOne();
1326+
1327+
// The spy and the original function got called.
1328+
expect(methodOneCalls).toBe(1);
1329+
expect(spy1.mock.calls).toHaveLength(1);
1330+
1331+
expect(moduleMocker.isMockFunction(obj.methodOne)).toBe(true);
1332+
1333+
spy1.mockRestore();
1334+
1335+
// After restoring the spy, the method is not mock function.
1336+
expect(moduleMocker.isMockFunction(obj.methodOne)).toBe(false);
1337+
1338+
obj.methodOne();
1339+
1340+
// After restoring the spy only the real method bumps its call count, not the spy.
1341+
expect(methodOneCalls).toBe(2);
1342+
expect(spy1.mock.calls).toHaveLength(0);
1343+
});
1344+
13151345
it('supports restoring all spies', () => {
13161346
let methodOneCalls = 0;
13171347
let methodTwoCalls = 0;
@@ -1327,25 +1357,32 @@ describe('moduleMocker', () => {
13271357
const spy1 = moduleMocker.spyOn(obj, 'methodOne');
13281358
const spy2 = moduleMocker.spyOn(obj, 'methodTwo');
13291359

1330-
// First, we call with the spies: both spies and both original functions
1331-
// should be called.
13321360
obj.methodOne();
13331361
obj.methodTwo();
1362+
1363+
// Both spies and both original functions got called.
13341364
expect(methodOneCalls).toBe(1);
13351365
expect(methodTwoCalls).toBe(1);
13361366
expect(spy1.mock.calls).toHaveLength(1);
13371367
expect(spy2.mock.calls).toHaveLength(1);
13381368

1369+
expect(moduleMocker.isMockFunction(obj.methodOne)).toBe(true);
1370+
expect(moduleMocker.isMockFunction(obj.methodTwo)).toBe(true);
1371+
13391372
moduleMocker.restoreAllMocks();
13401373

1341-
// Then, after resetting all mocks, we call methods again. Only the real
1342-
// methods should bump their count, not the spies.
1374+
// After restoring all mocks, the methods are not mock functions.
1375+
expect(moduleMocker.isMockFunction(obj.methodOne)).toBe(false);
1376+
expect(moduleMocker.isMockFunction(obj.methodTwo)).toBe(false);
1377+
13431378
obj.methodOne();
13441379
obj.methodTwo();
1380+
1381+
// After restoring all mocks only the real methods bump their count, not the spies.
13451382
expect(methodOneCalls).toBe(2);
13461383
expect(methodTwoCalls).toBe(2);
1347-
expect(spy1.mock.calls).toHaveLength(1);
1348-
expect(spy2.mock.calls).toHaveLength(1);
1384+
expect(spy1.mock.calls).toHaveLength(0);
1385+
expect(spy2.mock.calls).toHaveLength(0);
13491386
});
13501387

13511388
it('should work with getters', () => {
@@ -1482,6 +1519,33 @@ describe('moduleMocker', () => {
14821519
);
14831520
});
14841521

1522+
it('supports restoring a spy', () => {
1523+
let methodOneCalls = 0;
1524+
const obj = {
1525+
get methodOne() {
1526+
return function () {
1527+
methodOneCalls++;
1528+
};
1529+
},
1530+
};
1531+
1532+
const spy1 = moduleMocker.spyOn(obj, 'methodOne', 'get');
1533+
1534+
obj.methodOne();
1535+
1536+
// The spy and the original function are called.
1537+
expect(methodOneCalls).toBe(1);
1538+
expect(spy1.mock.calls).toHaveLength(1);
1539+
1540+
spy1.mockRestore();
1541+
1542+
obj.methodOne();
1543+
1544+
// After restoring the spy only the real method bumps its call count, not the spy.
1545+
expect(methodOneCalls).toBe(2);
1546+
expect(spy1.mock.calls).toHaveLength(0);
1547+
});
1548+
14851549
it('supports restoring all spies', () => {
14861550
let methodOneCalls = 0;
14871551
let methodTwoCalls = 0;
@@ -1501,25 +1565,25 @@ describe('moduleMocker', () => {
15011565
const spy1 = moduleMocker.spyOn(obj, 'methodOne', 'get');
15021566
const spy2 = moduleMocker.spyOn(obj, 'methodTwo', 'get');
15031567

1504-
// First, we call with the spies: both spies and both original functions
1505-
// should be called.
15061568
obj.methodOne();
15071569
obj.methodTwo();
1570+
1571+
// Both spies and both original functions got called.
15081572
expect(methodOneCalls).toBe(1);
15091573
expect(methodTwoCalls).toBe(1);
15101574
expect(spy1.mock.calls).toHaveLength(1);
15111575
expect(spy2.mock.calls).toHaveLength(1);
15121576

15131577
moduleMocker.restoreAllMocks();
15141578

1515-
// Then, after resetting all mocks, we call methods again. Only the real
1516-
// methods should bump their count, not the spies.
15171579
obj.methodOne();
15181580
obj.methodTwo();
1581+
1582+
// After restoring all mocks only the real methods bump their count, not the spies.
15191583
expect(methodOneCalls).toBe(2);
15201584
expect(methodTwoCalls).toBe(2);
1521-
expect(spy1.mock.calls).toHaveLength(1);
1522-
expect(spy2.mock.calls).toHaveLength(1);
1585+
expect(spy1.mock.calls).toHaveLength(0);
1586+
expect(spy2.mock.calls).toHaveLength(0);
15231587
});
15241588

15251589
it('should work with getters on the prototype chain', () => {
@@ -1587,6 +1651,34 @@ describe('moduleMocker', () => {
15871651
expect(obj.property).toBe(true);
15881652
});
15891653

1654+
it('supports restoring a spy on the prototype chain', () => {
1655+
let methodOneCalls = 0;
1656+
const prototype = {
1657+
get methodOne() {
1658+
return function () {
1659+
methodOneCalls++;
1660+
};
1661+
},
1662+
};
1663+
const obj = Object.create(prototype, {});
1664+
1665+
const spy1 = moduleMocker.spyOn(obj, 'methodOne', 'get');
1666+
1667+
obj.methodOne();
1668+
1669+
// The spy and the original function are called.
1670+
expect(methodOneCalls).toBe(1);
1671+
expect(spy1.mock.calls).toHaveLength(1);
1672+
1673+
spy1.mockRestore();
1674+
1675+
obj.methodOne();
1676+
1677+
// After restoring the spy only the real method bumps its call count, not the spy.
1678+
expect(methodOneCalls).toBe(2);
1679+
expect(spy1.mock.calls).toHaveLength(0);
1680+
});
1681+
15901682
it('supports restoring all spies on the prototype chain', () => {
15911683
let methodOneCalls = 0;
15921684
let methodTwoCalls = 0;
@@ -1607,25 +1699,25 @@ describe('moduleMocker', () => {
16071699
const spy1 = moduleMocker.spyOn(obj, 'methodOne', 'get');
16081700
const spy2 = moduleMocker.spyOn(obj, 'methodTwo', 'get');
16091701

1610-
// First, we call with the spies: both spies and both original functions
1611-
// should be called.
16121702
obj.methodOne();
16131703
obj.methodTwo();
1704+
1705+
// Both spies and both original functions got called.
16141706
expect(methodOneCalls).toBe(1);
16151707
expect(methodTwoCalls).toBe(1);
16161708
expect(spy1.mock.calls).toHaveLength(1);
16171709
expect(spy2.mock.calls).toHaveLength(1);
16181710

16191711
moduleMocker.restoreAllMocks();
16201712

1621-
// Then, after resetting all mocks, we call methods again. Only the real
1622-
// methods should bump their count, not the spies.
16231713
obj.methodOne();
16241714
obj.methodTwo();
1715+
1716+
// After restoring all mocks only the real methods bump their count, not the spies.
16251717
expect(methodOneCalls).toBe(2);
16261718
expect(methodTwoCalls).toBe(2);
1627-
expect(spy1.mock.calls).toHaveLength(1);
1628-
expect(spy2.mock.calls).toHaveLength(1);
1719+
expect(spy1.mock.calls).toHaveLength(0);
1720+
expect(spy2.mock.calls).toHaveLength(0);
16291721
});
16301722
});
16311723

@@ -1664,7 +1756,7 @@ describe('moduleMocker', () => {
16641756
expect(obj.property).toBe(1);
16651757
});
16661758

1667-
it('should allow mocking with value of different value', () => {
1759+
it('should allow mocking with value of different type', () => {
16681760
const obj = {
16691761
property: 1,
16701762
};

packages/jest-mock/src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1414,6 +1414,7 @@ export class ModuleMocker {
14141414
}
14151415

14161416
restoreAllMocks(): void {
1417+
this._mockState = new WeakMap();
14171418
this._spyState.forEach(restore => restore());
14181419
this._spyState = new Set();
14191420
}

0 commit comments

Comments
 (0)