Skip to content

Commit 82e503f

Browse files
fix: mocking of getters/setters on automatically mocked classes (#13145)
Co-authored-by: Tom Mrazauskas <[email protected]>
1 parent 4adf6ab commit 82e503f

File tree

10 files changed

+680
-114
lines changed

10 files changed

+680
-114
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
- `[jest-circus, jest-jasmine2]` Fix error messages for Node's `assert.throes` ([#13322](https://github.com/facebook/jest/pull/13322))
1616
- `[jest-haste-map]` Remove `__proto__` usage ([#13256](https://github.com/facebook/jest/pull/13256))
1717
- `[jest-mock]` Improve `spyOn` typings to handle optional properties ([#13247](https://github.com/facebook/jest/pull/13247))
18+
- `[jest-mock]` Fix mocking of getters and setters on classes ([#13145](https://github.com/facebook/jest/pull/13145))
1819
- `[jest-snapshot]` Throw useful error when an array is passed as property matchers ([#13263](https://github.com/facebook/jest/pull/13263))
1920
- `[jest-snapshot]` Prioritize parser used in the project ([#13323](https://github.com/facebook/jest/pull/13323))
2021
- `[jest-transform]` Attempt to work around issues with atomic writes on Windows ([#11423](https://github.com/facebook/jest/pull/11423))

jest.config.mjs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ export default {
5858
'/packages/jest-haste-map/src/__tests__/haste_impl.js',
5959
'/packages/jest-haste-map/src/__tests__/dependencyExtractor.js',
6060
'/packages/jest-haste-map/src/__tests__/test_dotfiles_root/',
61+
'/packages/jest-mock/src/__tests__/class-mocks-types.ts',
62+
'/packages/jest-mock/src/__tests__/TestClass.ts',
63+
'/packages/jest-mock/src/__tests__/SuperTestClass.ts',
6164
'/packages/jest-repl/src/__tests__/test_root',
6265
'/packages/jest-resolve-dependencies/src/__tests__/__fixtures__/',
6366
'/packages/jest-runtime/src/__tests__/defaultResolver.js',
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
*/
8+
9+
export class SuperTestClass {
10+
static staticTestProperty = 'staticTestProperty';
11+
12+
static get staticTestAccessor(): string {
13+
return 'staticTestAccessor';
14+
}
15+
16+
static set staticTestAccessor(_x: string) {
17+
return;
18+
}
19+
20+
static staticTestMethod(): string {
21+
return 'staticTestMethod';
22+
}
23+
24+
testProperty = 'testProperty';
25+
26+
get testAccessor(): string {
27+
return 'testAccessor';
28+
}
29+
set testAccessor(_x: string) {
30+
return;
31+
}
32+
33+
testMethod(): string {
34+
return 'testMethod';
35+
}
36+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
*/
8+
9+
import {SuperTestClass} from './SuperTestClass';
10+
11+
export default class TestClass extends SuperTestClass {}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
*/
8+
9+
import {SuperTestClass} from './SuperTestClass';
10+
import TestClass from './TestClass';
11+
jest.mock('./SuperTestClass');
12+
jest.mock('./TestClass');
13+
14+
describe('Testing the mocking of a class hierarchy defined in multiple imports', () => {
15+
it('can call an instance method - Auto-mocked class', () => {
16+
const mockTestMethod = jest
17+
.spyOn(SuperTestClass.prototype, 'testMethod')
18+
.mockImplementation(() => {
19+
return 'mockTestMethod';
20+
});
21+
const testClassInstance = new SuperTestClass();
22+
expect(testClassInstance.testMethod()).toEqual('mockTestMethod');
23+
expect(mockTestMethod).toHaveBeenCalledTimes(1);
24+
25+
mockTestMethod.mockClear();
26+
});
27+
28+
it('can call a superclass instance method - Auto-mocked class', () => {
29+
const mockTestMethod = jest
30+
.spyOn(TestClass.prototype, 'testMethod')
31+
.mockImplementation(() => {
32+
return 'mockTestMethod';
33+
});
34+
const testClassInstance = new TestClass();
35+
expect(testClassInstance.testMethod()).toEqual('mockTestMethod');
36+
expect(mockTestMethod).toHaveBeenCalledTimes(1);
37+
});
38+
39+
it('can read a value from an instance getter - Auto-mocked class', () => {
40+
const mockTestMethod = jest
41+
.spyOn(SuperTestClass.prototype, 'testAccessor', 'get')
42+
.mockImplementation(() => {
43+
return 'mockTestAccessor';
44+
});
45+
const testClassInstance = new SuperTestClass();
46+
expect(testClassInstance.testAccessor).toEqual('mockTestAccessor');
47+
expect(mockTestMethod).toHaveBeenCalledTimes(1);
48+
49+
mockTestMethod.mockClear();
50+
});
51+
52+
it('can read a value from a superclass instance getter - Auto-mocked class', () => {
53+
const mockTestMethod = jest
54+
.spyOn(TestClass.prototype, 'testAccessor', 'get')
55+
.mockImplementation(() => {
56+
return 'mockTestAccessor';
57+
});
58+
const testClassInstance = new TestClass();
59+
expect(testClassInstance.testAccessor).toEqual('mockTestAccessor');
60+
expect(mockTestMethod).toHaveBeenCalledTimes(1);
61+
});
62+
63+
it('can write a value to an instance setter - Auto-mocked class', () => {
64+
const mockTestMethod = jest
65+
.spyOn(SuperTestClass.prototype, 'testAccessor', 'set')
66+
.mockImplementation((_x: string) => {
67+
return () => {};
68+
});
69+
const testClassInstance = new SuperTestClass();
70+
testClassInstance.testAccessor = '';
71+
expect(mockTestMethod).toHaveBeenCalledTimes(1);
72+
73+
mockTestMethod.mockClear();
74+
});
75+
76+
it('can write a value to a superclass instance setter - Auto-mocked class', () => {
77+
const mockTestMethod = jest
78+
.spyOn(TestClass.prototype, 'testAccessor', 'set')
79+
.mockImplementation((_x: string) => {
80+
return () => {};
81+
});
82+
const testClassInstance = new TestClass();
83+
testClassInstance.testAccessor = '';
84+
expect(mockTestMethod).toHaveBeenCalledTimes(1);
85+
});
86+
87+
it('can read a value from a static getter - Auto-mocked class', () => {
88+
const mockTestMethod = jest
89+
.spyOn(SuperTestClass, 'staticTestAccessor', 'get')
90+
.mockImplementation(() => {
91+
return 'mockStaticTestAccessor';
92+
});
93+
expect(SuperTestClass.staticTestAccessor).toEqual('mockStaticTestAccessor');
94+
expect(mockTestMethod).toHaveBeenCalledTimes(1);
95+
96+
mockTestMethod.mockClear();
97+
});
98+
99+
it('can read a value from a superclass static getter - Auto-mocked class', () => {
100+
const mockTestMethod = jest
101+
.spyOn(TestClass, 'staticTestAccessor', 'get')
102+
.mockImplementation(() => {
103+
return 'mockStaticTestAccessor';
104+
});
105+
expect(TestClass.staticTestAccessor).toEqual('mockStaticTestAccessor');
106+
expect(mockTestMethod).toHaveBeenCalledTimes(1);
107+
});
108+
109+
it('can write a value to a static setter - Auto-mocked class', () => {
110+
const mockTestMethod = jest
111+
.spyOn(SuperTestClass, 'staticTestAccessor', 'set')
112+
.mockImplementation((_x: string) => {
113+
return () => {};
114+
});
115+
SuperTestClass.staticTestAccessor = '';
116+
expect(mockTestMethod).toHaveBeenCalledTimes(1);
117+
118+
mockTestMethod.mockClear();
119+
});
120+
121+
it('can write a value to a superclass static setter - Auto-mocked class', () => {
122+
const mockTestMethod = jest
123+
.spyOn(TestClass, 'staticTestAccessor', 'set')
124+
.mockImplementation((_x: string) => {
125+
return () => {};
126+
});
127+
TestClass.staticTestAccessor = '';
128+
expect(mockTestMethod).toHaveBeenCalledTimes(1);
129+
});
130+
});
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
*/
8+
9+
import SuperTestClass, {TestClass} from './class-mocks-types';
10+
jest.mock('./class-mocks-types');
11+
12+
describe('Testing the mocking of a class hierarchy defined in a single import', () => {
13+
it('can call an instance method - Auto-mocked class', () => {
14+
const mockTestMethod = jest
15+
.spyOn(SuperTestClass.prototype, 'testMethod')
16+
.mockImplementation(() => {
17+
return 'mockTestMethod';
18+
});
19+
const testClassInstance = new SuperTestClass();
20+
expect(testClassInstance.testMethod()).toEqual('mockTestMethod');
21+
expect(mockTestMethod).toHaveBeenCalledTimes(1);
22+
23+
mockTestMethod.mockClear();
24+
});
25+
26+
it('can call a superclass instance method - Auto-mocked class', () => {
27+
const mockTestMethod = jest
28+
.spyOn(TestClass.prototype, 'testMethod')
29+
.mockImplementation(() => {
30+
return 'mockTestMethod';
31+
});
32+
const testClassInstance = new TestClass();
33+
expect(testClassInstance.testMethod()).toEqual('mockTestMethod');
34+
expect(mockTestMethod).toHaveBeenCalledTimes(1);
35+
});
36+
37+
it('can read a value from an instance getter - Auto-mocked class', () => {
38+
const mockTestMethod = jest
39+
.spyOn(SuperTestClass.prototype, 'testAccessor', 'get')
40+
.mockImplementation(() => {
41+
return 'mockTestAccessor';
42+
});
43+
const testClassInstance = new SuperTestClass();
44+
expect(testClassInstance.testAccessor).toEqual('mockTestAccessor');
45+
expect(mockTestMethod).toHaveBeenCalledTimes(1);
46+
47+
mockTestMethod.mockClear();
48+
});
49+
50+
it('can read a value from a superclass instance getter - Auto-mocked class', () => {
51+
const mockTestMethod = jest
52+
.spyOn(TestClass.prototype, 'testAccessor', 'get')
53+
.mockImplementation(() => {
54+
return 'mockTestAccessor';
55+
});
56+
const testClassInstance = new TestClass();
57+
expect(testClassInstance.testAccessor).toEqual('mockTestAccessor');
58+
expect(mockTestMethod).toHaveBeenCalledTimes(1);
59+
});
60+
61+
it('can write a value to an instance setter - Auto-mocked class', () => {
62+
const mockTestMethod = jest
63+
.spyOn(SuperTestClass.prototype, 'testAccessor', 'set')
64+
.mockImplementation((_x: string) => {
65+
return () => {};
66+
});
67+
const testClassInstance = new SuperTestClass();
68+
testClassInstance.testAccessor = '';
69+
expect(mockTestMethod).toHaveBeenCalledTimes(1);
70+
71+
mockTestMethod.mockClear();
72+
});
73+
74+
it('can write a value to a superclass instance setter - Auto-mocked class', () => {
75+
const mockTestMethod = jest
76+
.spyOn(TestClass.prototype, 'testAccessor', 'set')
77+
.mockImplementation((_x: string) => {
78+
return () => {};
79+
});
80+
const testClassInstance = new TestClass();
81+
testClassInstance.testAccessor = '';
82+
expect(mockTestMethod).toHaveBeenCalledTimes(1);
83+
});
84+
85+
it('can read a value from a static getter - Auto-mocked class', () => {
86+
const mockTestMethod = jest
87+
.spyOn(SuperTestClass, 'staticTestAccessor', 'get')
88+
.mockImplementation(() => {
89+
return 'mockStaticTestAccessor';
90+
});
91+
expect(SuperTestClass.staticTestAccessor).toEqual('mockStaticTestAccessor');
92+
expect(mockTestMethod).toHaveBeenCalledTimes(1);
93+
94+
mockTestMethod.mockClear();
95+
});
96+
97+
it('can read a value from a superclass static getter - Auto-mocked class', () => {
98+
const mockTestMethod = jest
99+
.spyOn(TestClass, 'staticTestAccessor', 'get')
100+
.mockImplementation(() => {
101+
return 'mockStaticTestAccessor';
102+
});
103+
expect(TestClass.staticTestAccessor).toEqual('mockStaticTestAccessor');
104+
expect(mockTestMethod).toHaveBeenCalledTimes(1);
105+
});
106+
107+
it('can write a value to a static setter - Auto-mocked class', () => {
108+
const mockTestMethod = jest
109+
.spyOn(SuperTestClass, 'staticTestAccessor', 'set')
110+
.mockImplementation((_x: string) => {
111+
return () => {};
112+
});
113+
SuperTestClass.staticTestAccessor = '';
114+
expect(mockTestMethod).toHaveBeenCalledTimes(1);
115+
116+
mockTestMethod.mockClear();
117+
});
118+
119+
it('can write a value to a superclass static setter - Auto-mocked class', () => {
120+
const mockTestMethod = jest
121+
.spyOn(TestClass, 'staticTestAccessor', 'set')
122+
.mockImplementation((_x: string) => {
123+
return () => {};
124+
});
125+
TestClass.staticTestAccessor = '';
126+
expect(mockTestMethod).toHaveBeenCalledTimes(1);
127+
});
128+
});
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
*/
8+
9+
export default class SuperTestClass {
10+
static staticTestProperty = 'staticTestProperty';
11+
12+
static get staticTestAccessor(): string {
13+
return 'staticTestAccessor';
14+
}
15+
16+
static set staticTestAccessor(_x: string) {
17+
return;
18+
}
19+
20+
static staticTestMethod(): string {
21+
return 'staticTestMethod';
22+
}
23+
24+
testProperty = 'testProperty';
25+
26+
get testAccessor(): string {
27+
return 'testAccessor';
28+
}
29+
set testAccessor(_x: string) {
30+
return;
31+
}
32+
33+
testMethod(): string {
34+
return 'testMethod';
35+
}
36+
}
37+
38+
export class TestClass extends SuperTestClass {}

0 commit comments

Comments
 (0)