-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Prevent false test failures caused by promise rejections handled asyn…
…chronously (#14315)
- Loading branch information
Showing
28 changed files
with
772 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
e2e/__tests__/__snapshots__/environmentAfterTeardown.test.ts.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
e2e/__tests__/__snapshots__/environmentAfterTeardownJasmine.test.ts.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`prints useful error for environment methods after test is done 1`] = ` | ||
"ReferenceError: You are trying to access a property or method of the Jest environment after it has been torn down. From __tests__/afterTeardown.test.js. | ||
9 | test('access environment methods after done', () => { | ||
10 | setTimeout(() => { | ||
> 11 | jest.clearAllTimers(); | ||
| ^ | ||
12 | }, 0); | ||
13 | }); | ||
14 |" | ||
`; |
236 changes: 236 additions & 0 deletions
236
e2e/__tests__/__snapshots__/promiseAsyncHandling.test.ts.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,236 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`fails because of unhandled promise rejection in afterAll hook 1`] = ` | ||
Object { | ||
"rest": "FAIL __tests__/unhandledRejectionAfterAll.test.js | ||
● Test suite failed to run | ||
REJECTED | ||
11 | | ||
12 | afterAll(async () => { | ||
> 13 | Promise.reject(new Error('REJECTED')); | ||
| ^ | ||
14 | | ||
15 | await promisify(setTimeout)(0); | ||
16 | }); | ||
at Object.<anonymous> (__tests__/unhandledRejectionAfterAll.test.js:13:18)", | ||
"summary": "Test Suites: 1 failed, 1 total | ||
Tests: 1 passed, 1 total | ||
Snapshots: 0 total | ||
Time: <<REPLACED>> | ||
Ran all test suites matching /unhandledRejectionAfterAll.test.js/i.", | ||
} | ||
`; | ||
exports[`fails because of unhandled promise rejection in afterEach hook 1`] = ` | ||
Object { | ||
"rest": "FAIL __tests__/unhandledRejectionAfterEach.test.js | ||
✕ foo #1 | ||
✕ foo #2 | ||
● foo #1 | ||
REJECTED | ||
11 | | ||
12 | afterEach(async () => { | ||
> 13 | Promise.reject(new Error('REJECTED')); | ||
| ^ | ||
14 | | ||
15 | await promisify(setTimeout)(0); | ||
16 | }); | ||
at Object.<anonymous> (__tests__/unhandledRejectionAfterEach.test.js:13:18) | ||
● foo #2 | ||
REJECTED | ||
11 | | ||
12 | afterEach(async () => { | ||
> 13 | Promise.reject(new Error('REJECTED')); | ||
| ^ | ||
14 | | ||
15 | await promisify(setTimeout)(0); | ||
16 | }); | ||
at Object.<anonymous> (__tests__/unhandledRejectionAfterEach.test.js:13:18)", | ||
"summary": "Test Suites: 1 failed, 1 total | ||
Tests: 2 failed, 2 total | ||
Snapshots: 0 total | ||
Time: <<REPLACED>> | ||
Ran all test suites matching /unhandledRejectionAfterEach.test.js/i.", | ||
} | ||
`; | ||
exports[`fails because of unhandled promise rejection in beforeAll hook 1`] = ` | ||
Object { | ||
"rest": "FAIL __tests__/unhandledRejectionBeforeAll.test.js | ||
✕ foo | ||
● foo | ||
REJECTED | ||
11 | | ||
12 | beforeAll(async () => { | ||
> 13 | Promise.reject(new Error('REJECTED')); | ||
| ^ | ||
14 | | ||
15 | await promisify(setTimeout)(0); | ||
16 | }); | ||
at Object.<anonymous> (__tests__/unhandledRejectionBeforeAll.test.js:13:18)", | ||
"summary": "Test Suites: 1 failed, 1 total | ||
Tests: 1 failed, 1 total | ||
Snapshots: 0 total | ||
Time: <<REPLACED>> | ||
Ran all test suites matching /unhandledRejectionBeforeAll.test.js/i.", | ||
} | ||
`; | ||
exports[`fails because of unhandled promise rejection in beforeEach hook 1`] = ` | ||
Object { | ||
"rest": "FAIL __tests__/unhandledRejectionBeforeEach.test.js | ||
✕ foo #1 | ||
✕ foo #2 | ||
● foo #1 | ||
REJECTED | ||
11 | | ||
12 | beforeEach(async () => { | ||
> 13 | Promise.reject(new Error('REJECTED')); | ||
| ^ | ||
14 | | ||
15 | await promisify(setTimeout)(0); | ||
16 | }); | ||
at Object.<anonymous> (__tests__/unhandledRejectionBeforeEach.test.js:13:18) | ||
● foo #2 | ||
REJECTED | ||
11 | | ||
12 | beforeEach(async () => { | ||
> 13 | Promise.reject(new Error('REJECTED')); | ||
| ^ | ||
14 | | ||
15 | await promisify(setTimeout)(0); | ||
16 | }); | ||
at Object.<anonymous> (__tests__/unhandledRejectionBeforeEach.test.js:13:18)", | ||
"summary": "Test Suites: 1 failed, 1 total | ||
Tests: 2 failed, 2 total | ||
Snapshots: 0 total | ||
Time: <<REPLACED>> | ||
Ran all test suites matching /unhandledRejectionBeforeEach.test.js/i.", | ||
} | ||
`; | ||
exports[`fails because of unhandled promise rejection in test 1`] = ` | ||
Object { | ||
"rest": "FAIL __tests__/unhandledRejectionTest.test.js | ||
✕ w/o event loop turn after rejection | ||
✕ w/ event loop turn after rejection in async function | ||
✕ w/ event loop turn after rejection in sync function | ||
✕ combined w/ another failure _after_ promise rejection | ||
● w/o event loop turn after rejection | ||
REJECTED | ||
11 | | ||
12 | test('w/o event loop turn after rejection', () => { | ||
> 13 | Promise.reject(new Error('REJECTED')); | ||
| ^ | ||
14 | }); | ||
15 | | ||
16 | test('w/ event loop turn after rejection in async function', async () => { | ||
at Object.<anonymous> (__tests__/unhandledRejectionTest.test.js:13:18) | ||
● w/ event loop turn after rejection in async function | ||
REJECTED | ||
15 | | ||
16 | test('w/ event loop turn after rejection in async function', async () => { | ||
> 17 | Promise.reject(new Error('REJECTED')); | ||
| ^ | ||
18 | | ||
19 | await promisify(setTimeout)(0); | ||
20 | }); | ||
at Object.<anonymous> (__tests__/unhandledRejectionTest.test.js:17:18) | ||
● w/ event loop turn after rejection in sync function | ||
REJECTED | ||
21 | | ||
22 | test('w/ event loop turn after rejection in sync function', done => { | ||
> 23 | Promise.reject(new Error('REJECTED')); | ||
| ^ | ||
24 | | ||
25 | setTimeout(done, 0); | ||
26 | }); | ||
at Object.<anonymous> (__tests__/unhandledRejectionTest.test.js:23:18) | ||
● combined w/ another failure _after_ promise rejection | ||
expect(received).toBe(expected) // Object.is equality | ||
Expected: false | ||
Received: true | ||
31 | await promisify(setTimeout)(0); | ||
32 | | ||
> 33 | expect(true).toBe(false); | ||
| ^ | ||
34 | }); | ||
35 | | ||
at Object.toBe (__tests__/unhandledRejectionTest.test.js:33:16) | ||
● combined w/ another failure _after_ promise rejection | ||
REJECTED | ||
27 | | ||
28 | test('combined w/ another failure _after_ promise rejection', async () => { | ||
> 29 | Promise.reject(new Error('REJECTED')); | ||
| ^ | ||
30 | | ||
31 | await promisify(setTimeout)(0); | ||
32 | | ||
at Object.<anonymous> (__tests__/unhandledRejectionTest.test.js:29:18)", | ||
"summary": "Test Suites: 1 failed, 1 total | ||
Tests: 4 failed, 4 total | ||
Snapshots: 0 total | ||
Time: <<REPLACED>> | ||
Ran all test suites matching /unhandledRejectionTest.test.js/i.", | ||
} | ||
`; | ||
exports[`succeeds for async handled promise rejections 1`] = ` | ||
Object { | ||
"rest": "PASS __tests__/rejectionHandled.test.js | ||
✓ async function succeeds because the promise is eventually awaited by assertion | ||
✓ async function succeeds because the promise is eventually directly awaited | ||
✓ sync function succeeds because the promise is eventually handled by \`.catch\` handler", | ||
"summary": "Test Suites: 1 passed, 1 total | ||
Tests: 3 passed, 3 total | ||
Snapshots: 0 total | ||
Time: <<REPLACED>> | ||
Ran all test suites matching /rejectionHandled.test.js/i.", | ||
} | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
e2e/__tests__/__snapshots__/requireAfterTeardownJasmine.test.ts.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`prints useful error for requires after test is done 1`] = ` | ||
"ReferenceError: You are trying to \`import\` a file after the Jest environment has been torn down. From __tests__/lateRequire.test.js. | ||
9 | test('require after done', () => { | ||
10 | setTimeout(() => { | ||
> 11 | const double = require('../'); | ||
| ^ | ||
12 | | ||
13 | expect(double(5)).toBe(10); | ||
14 | }, 0);" | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/** | ||
* Copyright (c) Meta Platforms, Inc. and affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
import {skipSuiteOnJestCircus} from '@jest/test-utils'; | ||
import runJest from '../runJest'; | ||
|
||
skipSuiteOnJestCircus(); | ||
|
||
test('prints useful error for environment methods after test is done', () => { | ||
const {stderr} = runJest('environment-after-teardown'); | ||
const interestingLines = stderr.split('\n').slice(9, 18).join('\n'); | ||
|
||
expect(interestingLines).toMatchSnapshot(); | ||
expect(stderr.split('\n')[9]).toBe( | ||
'ReferenceError: You are trying to access a property or method of the Jest environment after it has been torn down. From __tests__/afterTeardown.test.js.', | ||
); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.