Skip to content

Commit dda54df

Browse files
committed
Merge branch 'main' into fix/issue-14427
2 parents 8b87509 + 085f063 commit dda54df

7 files changed

Lines changed: 151 additions & 169 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
- `[expect]` Remove `@types/node` from dependencies ([#14385](https://github.com/jestjs/jest/pull/14385))
99
- `[jest-core]` Use workers in watch mode by default to avoid crashes ([#14059](https://github.com/facebook/jest/pull/14059) & [#14085](https://github.com/facebook/jest/pull/14085)).
1010
- `[jest-reporters]` Update `istanbul-lib-instrument` dependency to v6. ([#14401](https://github.com/jestjs/jest/pull/14401))
11+
- `[jest-mock]` Revert [#13692](https://github.com/jestjs/jest/pull/13692) as it was a breaking change ([#14429](https://github.com/jestjs/jest/pull/14429))
12+
- `[jest-mock]` Revert [#13866](https://github.com/jestjs/jest/pull/13866) as it was a breaking change ([#14429](https://github.com/jestjs/jest/pull/14429))
13+
- `[jest-mock]` Revert [#13867](https://github.com/jestjs/jest/pull/13867) as it was a breaking change ([#14429](https://github.com/jestjs/jest/pull/14429))
1114

1215
### Chore & Maintenance
1316

docs/MockFunctionAPI.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,7 @@ Beware that `mockFn.mockClear()` will replace `mockFn.mock`, not just reset the
128128

129129
### `mockFn.mockReset()`
130130

131-
Does everything that [`mockFn.mockClear()`](#mockfnmockclear) does, and also removes any mocked return values or implementations.
132-
133-
This is useful when you want to completely reset a _mock_ back to its initial state.
131+
Does everything that [`mockFn.mockClear()`](#mockfnmockclear) does, and also replaces the mock implementation with an empty function, returning `undefined`.
134132

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

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

Lines changed: 97 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,26 @@ describe('moduleMocker', () => {
598598
expect(fn2()).not.toBe('abcd');
599599
});
600600

601+
it('is not affected by restoreAllMocks', () => {
602+
const fn1 = moduleMocker.fn();
603+
fn1.mockImplementation(() => 'abcd');
604+
fn1(1, 2, 3);
605+
expect(fn1.mock.calls).toEqual([[1, 2, 3]]);
606+
moduleMocker.restoreAllMocks();
607+
expect(fn1(1)).toBe('abcd');
608+
expect(fn1.mock.calls).toEqual([[1, 2, 3], [1]]);
609+
});
610+
611+
it('is cleared and stubbed when restored explicitly', () => {
612+
const fn1 = moduleMocker.fn();
613+
fn1.mockImplementation(() => 'abcd');
614+
fn1(1, 2, 3);
615+
expect(fn1.mock.calls).toEqual([[1, 2, 3]]);
616+
fn1.mockRestore();
617+
expect(fn1(1)).toBeUndefined();
618+
expect(fn1.mock.calls).toEqual([[1]]);
619+
});
620+
601621
it('maintains function arity', () => {
602622
const mockFunctionArity1 = moduleMocker.fn(x => x);
603623
const mockFunctionArity2 = moduleMocker.fn((x, y) => y);
@@ -1547,18 +1567,21 @@ describe('moduleMocker', () => {
15471567
});
15481568

15491569
it('supports resetting a spy', () => {
1550-
const methodOneReturn = 0;
1570+
const methodOneReturn = 10;
1571+
let methodOneRealCalls = 0;
15511572
const obj = {
15521573
methodOne() {
1574+
methodOneRealCalls++;
15531575
return methodOneReturn;
15541576
},
15551577
};
15561578

1557-
const spy1 = moduleMocker.spyOn(obj, 'methodOne').mockReturnValue(10);
1579+
const spy1 = moduleMocker.spyOn(obj, 'methodOne').mockReturnValue(100);
15581580

15591581
// Return value is mocked.
1560-
expect(methodOneReturn).toBe(0);
1561-
expect(obj.methodOne()).toBe(10);
1582+
expect(obj.methodOne()).toBe(100);
1583+
// Real impl has not been used.
1584+
expect(methodOneRealCalls).toBe(0);
15621585

15631586
expect(moduleMocker.isMockFunction(obj.methodOne)).toBe(true);
15641587

@@ -1567,32 +1590,45 @@ describe('moduleMocker', () => {
15671590
// After resetting the spy, the method is still mock functions.
15681591
expect(moduleMocker.isMockFunction(obj.methodOne)).toBe(true);
15691592

1570-
// After resetting the spy, the method returns the original return value.
1571-
expect(methodOneReturn).toBe(0);
1572-
expect(obj.methodOne()).toBe(0);
1593+
// After resetting the spy, the method returns undefined.
1594+
expect(obj.methodOne()).toBeUndefined();
1595+
1596+
// Real implementation has still not been called.
1597+
expect(methodOneRealCalls).toBe(0);
15731598
});
15741599

15751600
it('supports resetting all spies', () => {
15761601
const methodOneReturn = 10;
1577-
const methodTwoReturn = 20;
1602+
const methodTwoReturn = {};
1603+
let methodOneRealCalls = 0;
1604+
let methodTwoRealCalls = 0;
15781605
const obj = {
15791606
methodOne() {
1607+
methodOneRealCalls++;
15801608
return methodOneReturn;
15811609
},
15821610
methodTwo() {
1611+
methodTwoRealCalls++;
15831612
return methodTwoReturn;
15841613
},
15851614
};
15861615

1616+
// methodOne is spied on and mocked.
15871617
moduleMocker.spyOn(obj, 'methodOne').mockReturnValue(100);
1588-
moduleMocker.spyOn(obj, 'methodTwo').mockReturnValue(200);
1618+
// methodTwo is spied on but not mocked.
1619+
moduleMocker.spyOn(obj, 'methodTwo');
15891620

15901621
// Return values are mocked.
1591-
expect(methodOneReturn).toBe(10);
1592-
expect(methodTwoReturn).toBe(20);
15931622
expect(obj.methodOne()).toBe(100);
1594-
expect(obj.methodTwo()).toBe(200);
1623+
expect(obj.methodTwo()).toBe(methodTwoReturn);
15951624

1625+
// The real implementation has not been called when mocked.
1626+
expect(methodOneRealCalls).toBe(0);
1627+
1628+
// But has for the unmocked spy.
1629+
expect(methodTwoRealCalls).toBe(1);
1630+
1631+
// Both are mock functions.
15961632
expect(moduleMocker.isMockFunction(obj.methodOne)).toBe(true);
15971633
expect(moduleMocker.isMockFunction(obj.methodTwo)).toBe(true);
15981634

@@ -1602,11 +1638,16 @@ describe('moduleMocker', () => {
16021638
expect(moduleMocker.isMockFunction(obj.methodOne)).toBe(true);
16031639
expect(moduleMocker.isMockFunction(obj.methodTwo)).toBe(true);
16041640

1605-
// After resetting all mocks, the methods return the original return value.
1606-
expect(methodOneReturn).toBe(10);
1607-
expect(methodTwoReturn).toBe(20);
1608-
expect(obj.methodOne()).toBe(10);
1609-
expect(obj.methodTwo()).toBe(20);
1641+
// After resetting all mocks, the methods are stubs returning undefined.
1642+
expect(obj.methodOne()).toBeUndefined();
1643+
1644+
// NB: It may not be desirable for reset to stub a spy that was never mocked -
1645+
// consider changing in a future major.
1646+
expect(obj.methodTwo()).toBeUndefined();
1647+
1648+
// Real functions have not been called any more times.
1649+
expect(methodOneRealCalls).toBe(0);
1650+
expect(methodTwoRealCalls).toBe(1);
16101651
});
16111652

16121653
it('supports restoring a spy', () => {
@@ -1654,32 +1695,25 @@ describe('moduleMocker', () => {
16541695
const spy1 = moduleMocker.spyOn(obj, 'methodOne');
16551696
const spy2 = moduleMocker.spyOn(obj, 'methodTwo');
16561697

1698+
// First, we call with the spies: both spies and both original functions
1699+
// should be called.
16571700
obj.methodOne();
16581701
obj.methodTwo();
1659-
1660-
// Both spies and both original functions got called.
16611702
expect(methodOneCalls).toBe(1);
16621703
expect(methodTwoCalls).toBe(1);
16631704
expect(spy1.mock.calls).toHaveLength(1);
16641705
expect(spy2.mock.calls).toHaveLength(1);
16651706

1666-
expect(moduleMocker.isMockFunction(obj.methodOne)).toBe(true);
1667-
expect(moduleMocker.isMockFunction(obj.methodTwo)).toBe(true);
1668-
16691707
moduleMocker.restoreAllMocks();
16701708

1671-
// After restoring all mocks, the methods are not mock functions.
1672-
expect(moduleMocker.isMockFunction(obj.methodOne)).toBe(false);
1673-
expect(moduleMocker.isMockFunction(obj.methodTwo)).toBe(false);
1674-
1709+
// Then, after resetting all mocks, we call methods again. Only the real
1710+
// methods should bump their count, not the spies.
16751711
obj.methodOne();
16761712
obj.methodTwo();
1677-
1678-
// After restoring all mocks only the real methods bump their count, not the spies.
16791713
expect(methodOneCalls).toBe(2);
16801714
expect(methodTwoCalls).toBe(2);
1681-
expect(spy1.mock.calls).toHaveLength(0);
1682-
expect(spy2.mock.calls).toHaveLength(0);
1715+
expect(spy1.mock.calls).toHaveLength(1);
1716+
expect(spy2.mock.calls).toHaveLength(1);
16831717
});
16841718

16851719
it('should work with getters', () => {
@@ -1816,8 +1850,10 @@ describe('moduleMocker', () => {
18161850

18171851
it('supports resetting a spy', () => {
18181852
const methodOneReturn = 0;
1853+
let methodOneRealCalls = 0;
18191854
const obj = {
18201855
get methodOne() {
1856+
methodOneRealCalls++;
18211857
return methodOneReturn;
18221858
},
18231859
};
@@ -1827,14 +1863,13 @@ describe('moduleMocker', () => {
18271863
.mockReturnValue(10);
18281864

18291865
// Return value is mocked.
1830-
expect(methodOneReturn).toBe(0);
18311866
expect(obj.methodOne).toBe(10);
18321867

18331868
spy1.mockReset();
18341869

1835-
// After resetting the spy, the method returns the original return value.
1836-
expect(methodOneReturn).toBe(0);
1837-
expect(obj.methodOne).toBe(0);
1870+
// After resetting the spy, the getter is a stub returning undefined
1871+
expect(obj.methodOne).toBeUndefined();
1872+
expect(methodOneRealCalls).toBe(0);
18381873
});
18391874

18401875
it('supports resetting all spies', () => {
@@ -1860,11 +1895,9 @@ describe('moduleMocker', () => {
18601895

18611896
moduleMocker.resetAllMocks();
18621897

1863-
// After resetting all mocks, the methods return the original return value.
1864-
expect(methodOneReturn).toBe(10);
1865-
expect(methodTwoReturn).toBe(20);
1866-
expect(obj.methodOne).toBe(10);
1867-
expect(obj.methodTwo).toBe(20);
1898+
// After resetting all mocks, the methods are stubs
1899+
expect(obj.methodOne).toBeUndefined();
1900+
expect(obj.methodTwo).toBeUndefined();
18681901
});
18691902

18701903
it('supports restoring a spy', () => {
@@ -1913,25 +1946,25 @@ describe('moduleMocker', () => {
19131946
const spy1 = moduleMocker.spyOn(obj, 'methodOne', 'get');
19141947
const spy2 = moduleMocker.spyOn(obj, 'methodTwo', 'get');
19151948

1949+
// First, we call with the spies: both spies and both original functions
1950+
// should be called.
19161951
obj.methodOne();
19171952
obj.methodTwo();
1918-
1919-
// Both spies and both original functions got called.
19201953
expect(methodOneCalls).toBe(1);
19211954
expect(methodTwoCalls).toBe(1);
19221955
expect(spy1.mock.calls).toHaveLength(1);
19231956
expect(spy2.mock.calls).toHaveLength(1);
19241957

19251958
moduleMocker.restoreAllMocks();
19261959

1960+
// Then, after resetting all mocks, we call methods again. Only the real
1961+
// methods should bump their count, not the spies.
19271962
obj.methodOne();
19281963
obj.methodTwo();
1929-
1930-
// After restoring all mocks only the real methods bump their count, not the spies.
19311964
expect(methodOneCalls).toBe(2);
19321965
expect(methodTwoCalls).toBe(2);
1933-
expect(spy1.mock.calls).toHaveLength(0);
1934-
expect(spy2.mock.calls).toHaveLength(0);
1966+
expect(spy1.mock.calls).toHaveLength(1);
1967+
expect(spy2.mock.calls).toHaveLength(1);
19351968
});
19361969

19371970
it('should work with getters on the prototype chain', () => {
@@ -2000,10 +2033,11 @@ describe('moduleMocker', () => {
20002033
});
20012034

20022035
it('supports resetting a spy on the prototype chain', () => {
2003-
const methodOneReturn = 0;
2036+
let methodOneRealCalls = 0;
20042037
const prototype = {
20052038
get methodOne() {
2006-
return methodOneReturn;
2039+
methodOneRealCalls++;
2040+
return 1;
20072041
},
20082042
};
20092043
const obj = Object.create(prototype, {});
@@ -2013,14 +2047,15 @@ describe('moduleMocker', () => {
20132047
.mockReturnValue(10);
20142048

20152049
// Return value is mocked.
2016-
expect(methodOneReturn).toBe(0);
20172050
expect(obj.methodOne).toBe(10);
20182051

20192052
spy1.mockReset();
20202053

2021-
// After resetting the spy, the method returns the original return value.
2022-
expect(methodOneReturn).toBe(0);
2023-
expect(obj.methodOne).toBe(0);
2054+
// After resetting the spy, the method is a stub.
2055+
expect(obj.methodOne).toBeUndefined();
2056+
2057+
// The real implementation has not been used.
2058+
expect(methodOneRealCalls).toBe(0);
20242059
});
20252060

20262061
it('supports resetting all spies on the prototype chain', () => {
@@ -2040,18 +2075,14 @@ describe('moduleMocker', () => {
20402075
moduleMocker.spyOn(obj, 'methodTwo', 'get').mockReturnValue(200);
20412076

20422077
// Return values are mocked.
2043-
expect(methodOneReturn).toBe(10);
2044-
expect(methodTwoReturn).toBe(20);
20452078
expect(obj.methodOne).toBe(100);
20462079
expect(obj.methodTwo).toBe(200);
20472080

20482081
moduleMocker.resetAllMocks();
20492082

2050-
// After resetting all mocks, the methods return the original return value.
2051-
expect(methodOneReturn).toBe(10);
2052-
expect(methodTwoReturn).toBe(20);
2053-
expect(obj.methodOne).toBe(10);
2054-
expect(obj.methodTwo).toBe(20);
2083+
// After resetting all mocks, the methods are stubs
2084+
expect(obj.methodOne).toBeUndefined();
2085+
expect(obj.methodTwo).toBeUndefined();
20552086
});
20562087

20572088
it('supports restoring a spy on the prototype chain', () => {
@@ -2069,7 +2100,7 @@ describe('moduleMocker', () => {
20692100

20702101
obj.methodOne();
20712102

2072-
// The spy and the original function are called.
2103+
// The spy and the original function are called, because we have not mocked it.
20732104
expect(methodOneCalls).toBe(1);
20742105
expect(spy1.mock.calls).toHaveLength(1);
20752106

@@ -2102,25 +2133,25 @@ describe('moduleMocker', () => {
21022133
const spy1 = moduleMocker.spyOn(obj, 'methodOne', 'get');
21032134
const spy2 = moduleMocker.spyOn(obj, 'methodTwo', 'get');
21042135

2136+
// First, we call with the spies: both spies and both original functions
2137+
// should be called.
21052138
obj.methodOne();
21062139
obj.methodTwo();
2107-
2108-
// Both spies and both original functions got called.
21092140
expect(methodOneCalls).toBe(1);
21102141
expect(methodTwoCalls).toBe(1);
21112142
expect(spy1.mock.calls).toHaveLength(1);
21122143
expect(spy2.mock.calls).toHaveLength(1);
21132144

21142145
moduleMocker.restoreAllMocks();
21152146

2147+
// Then, after resetting all mocks, we call methods again. Only the real
2148+
// methods should bump their count, not the spies.
21162149
obj.methodOne();
21172150
obj.methodTwo();
2118-
2119-
// After restoring all mocks only the real methods bump their count, not the spies.
21202151
expect(methodOneCalls).toBe(2);
21212152
expect(methodTwoCalls).toBe(2);
2122-
expect(spy1.mock.calls).toHaveLength(0);
2123-
expect(spy2.mock.calls).toHaveLength(0);
2153+
expect(spy1.mock.calls).toHaveLength(1);
2154+
expect(spy2.mock.calls).toHaveLength(1);
21242155
});
21252156
});
21262157

@@ -2159,7 +2190,7 @@ describe('moduleMocker', () => {
21592190
expect(obj.property).toBe(1);
21602191
});
21612192

2162-
it('should allow mocking with value of different type', () => {
2193+
it('should allow mocking with value of different value', () => {
21632194
const obj = {
21642195
property: 1,
21652196
};

0 commit comments

Comments
 (0)