From 1fe9c15cae20d8f740ded68fd258bacbe494653b Mon Sep 17 00:00:00 2001 From: Aditya Agarwal Date: Tue, 1 Mar 2022 23:39:56 +0530 Subject: [PATCH 1/3] fix #12522 --- .../version-27.5/TestingAsyncCode.md | 120 +++++++++--------- 1 file changed, 59 insertions(+), 61 deletions(-) diff --git a/website/versioned_docs/version-27.5/TestingAsyncCode.md b/website/versioned_docs/version-27.5/TestingAsyncCode.md index 432db44b3944..678722742983 100644 --- a/website/versioned_docs/version-27.5/TestingAsyncCode.md +++ b/website/versioned_docs/version-27.5/TestingAsyncCode.md @@ -5,9 +5,66 @@ title: Testing Asynchronous Code It's common in JavaScript for code to run asynchronously. When you have code that runs asynchronously, Jest needs to know when the code it is testing has completed, before it can move on to another test. Jest has several ways to handle this. -## Callbacks +## Promises + +If your code uses promises, there is a more straightforward way to handle asynchronous tests. Return a promise from your test, and Jest will wait for that promise to resolve. If the promise is rejected, the test will automatically fail. + +For example, let's say that `fetchData`, instead of using a callback, returns a promise that is supposed to resolve to the string `'peanut butter'`. We could test it with: + +```js +test('the data is peanut butter', () => { + return fetchData().then(data => { + expect(data).toBe('peanut butter'); + }); +}); +``` + +## Async/Await + +Alternatively, you can use `async` and `await` in your tests. To write an async test, use the `async` keyword in front of the function passed to `test`. For example, the same `fetchData` scenario can be tested with: + +```js +test('the data is peanut butter', async () => { + const data = await fetchData(); + expect(data).toBe('peanut butter'); +}); + +test('the fetch fails with an error', async () => { + expect.assertions(1); + try { + await fetchData(); + } catch (e) { + expect(e).toMatch('error'); + } +}); +``` + +You can combine `async` and `await` with `.resolves` or `.rejects`. + +```js +test('the data is peanut butter', async () => { + await expect(fetchData()).resolves.toBe('peanut butter'); +}); + +test('the fetch fails with an error', async () => { + await expect(fetchData()).rejects.toMatch('error'); +}); +``` + +In these cases, `async` and `await` are effectively syntactic sugar for the same logic as the promises example uses. + +Be sure to return the promise - if you omit this `return` statement, your test will complete before the promise returned from `fetchData` resolves and then() has a chance to execute the callback. + +If you expect a promise to be rejected, use the `.catch` method. Make sure to add `expect.assertions` to verify that a certain number of assertions are called. Otherwise, a fulfilled promise would not fail the test. -The most common asynchronous pattern is callbacks. +```js +test('the fetch fails with an error', () => { + expect.assertions(1); + return fetchData().catch(e => expect(e).toMatch('error')); +}); +``` + +## Callbacks For example, let's say that you have a `fetchData(callback)` function that fetches some data and calls `callback(data)` when it is complete. You want to test that this returned data is the string `'peanut butter'`. @@ -49,31 +106,6 @@ If the `expect` statement fails, it throws an error and `done()` is not called. _Note: `done()` should not be mixed with Promises as this tends to lead to memory leaks in your tests._ -## Promises - -If your code uses promises, there is a more straightforward way to handle asynchronous tests. Return a promise from your test, and Jest will wait for that promise to resolve. If the promise is rejected, the test will automatically fail. - -For example, let's say that `fetchData`, instead of using a callback, returns a promise that is supposed to resolve to the string `'peanut butter'`. We could test it with: - -```js -test('the data is peanut butter', () => { - return fetchData().then(data => { - expect(data).toBe('peanut butter'); - }); -}); -``` - -Be sure to return the promise - if you omit this `return` statement, your test will complete before the promise returned from `fetchData` resolves and then() has a chance to execute the callback. - -If you expect a promise to be rejected, use the `.catch` method. Make sure to add `expect.assertions` to verify that a certain number of assertions are called. Otherwise, a fulfilled promise would not fail the test. - -```js -test('the fetch fails with an error', () => { - expect.assertions(1); - return fetchData().catch(e => expect(e).toMatch('error')); -}); -``` - ## `.resolves` / `.rejects` You can also use the `.resolves` matcher in your expect statement, and Jest will wait for that promise to resolve. If the promise is rejected, the test will automatically fail. @@ -94,38 +126,4 @@ test('the fetch fails with an error', () => { }); ``` -## Async/Await - -Alternatively, you can use `async` and `await` in your tests. To write an async test, use the `async` keyword in front of the function passed to `test`. For example, the same `fetchData` scenario can be tested with: - -```js -test('the data is peanut butter', async () => { - const data = await fetchData(); - expect(data).toBe('peanut butter'); -}); - -test('the fetch fails with an error', async () => { - expect.assertions(1); - try { - await fetchData(); - } catch (e) { - expect(e).toMatch('error'); - } -}); -``` - -You can combine `async` and `await` with `.resolves` or `.rejects`. - -```js -test('the data is peanut butter', async () => { - await expect(fetchData()).resolves.toBe('peanut butter'); -}); - -test('the fetch fails with an error', async () => { - await expect(fetchData()).rejects.toMatch('error'); -}); -``` - -In these cases, `async` and `await` are effectively syntactic sugar for the same logic as the promises example uses. - None of these forms is particularly superior to the others, and you can mix and match them across a codebase or even in a single file. It just depends on which style you feel makes your tests simpler. From 735aa37c2d08133fbd12359c45820a1ef586594f Mon Sep 17 00:00:00 2001 From: Aditya Agarwal <50960175+adi611@users.noreply.github.com> Date: Tue, 8 Mar 2022 17:23:37 +0530 Subject: [PATCH 2/3] Apply suggestions from code review Co-authored-by: Simen Bekkhus --- .../versioned_docs/version-27.5/TestingAsyncCode.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/website/versioned_docs/version-27.5/TestingAsyncCode.md b/website/versioned_docs/version-27.5/TestingAsyncCode.md index 678722742983..5f7e7132f0e6 100644 --- a/website/versioned_docs/version-27.5/TestingAsyncCode.md +++ b/website/versioned_docs/version-27.5/TestingAsyncCode.md @@ -7,9 +7,9 @@ It's common in JavaScript for code to run asynchronously. When you have code tha ## Promises -If your code uses promises, there is a more straightforward way to handle asynchronous tests. Return a promise from your test, and Jest will wait for that promise to resolve. If the promise is rejected, the test will automatically fail. +Return a promise from your test, and Jest will wait for that promise to resolve. If the promise is rejected, the test will fail. -For example, let's say that `fetchData`, instead of using a callback, returns a promise that is supposed to resolve to the string `'peanut butter'`. We could test it with: +For example, let's say that `fetchData` returns a promise that is supposed to resolve to the string `'peanut butter'`. We could test it with: ```js test('the data is peanut butter', () => { @@ -53,7 +53,11 @@ test('the fetch fails with an error', async () => { In these cases, `async` and `await` are effectively syntactic sugar for the same logic as the promises example uses. -Be sure to return the promise - if you omit this `return` statement, your test will complete before the promise returned from `fetchData` resolves and then() has a chance to execute the callback. +:::caution + +Be sure to return (or `await`) the promise - if you omit the `return` statement, your test will complete before the promise returned from `fetchData` resolves and `then()` has a chance to execute the callback. + +::: If you expect a promise to be rejected, use the `.catch` method. Make sure to add `expect.assertions` to verify that a certain number of assertions are called. Otherwise, a fulfilled promise would not fail the test. @@ -66,7 +70,7 @@ test('the fetch fails with an error', () => { ## Callbacks -For example, let's say that you have a `fetchData(callback)` function that fetches some data and calls `callback(data)` when it is complete. You want to test that this returned data is the string `'peanut butter'`. +For example, let's say that `fetchData`, instead of returning a promise, expects a callback, i.e. fetches some data and calls `callback(data)` when it is complete. You want to test that this returned data is the string `'peanut butter'`. By default, Jest tests complete once they reach the end of their execution. That means this test will _not_ work as intended: From cc94ec5a3c443901542a5901063b72f81f6a2dbb Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Mon, 11 Apr 2022 09:45:54 +0200 Subject: [PATCH 3/3] all versions --- .eslintrc.cjs | 1 - docs/TestingAsyncCode.md | 137 ++++++++++-------- .../version-25.x/TestingAsyncCode.md | 137 ++++++++++-------- .../version-26.x/TestingAsyncCode.md | 137 ++++++++++-------- .../version-27.0/TestingAsyncCode.md | 137 ++++++++++-------- .../version-27.1/TestingAsyncCode.md | 137 ++++++++++-------- .../version-27.2/TestingAsyncCode.md | 137 ++++++++++-------- .../version-27.4/TestingAsyncCode.md | 137 ++++++++++-------- .../version-27.5/TestingAsyncCode.md | 15 +- 9 files changed, 522 insertions(+), 453 deletions(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 8ee5a68dfe67..64caddbf7457 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -375,7 +375,6 @@ module.exports = { 'no-bitwise': 'warn', 'no-caller': 'error', 'no-case-declarations': 'off', - 'no-catch-shadow': 'error', 'no-class-assign': 'warn', 'no-cond-assign': 'off', 'no-confusing-arrow': 'off', diff --git a/docs/TestingAsyncCode.md b/docs/TestingAsyncCode.md index 432db44b3944..ef8762eb7d87 100644 --- a/docs/TestingAsyncCode.md +++ b/docs/TestingAsyncCode.md @@ -5,18 +5,82 @@ title: Testing Asynchronous Code It's common in JavaScript for code to run asynchronously. When you have code that runs asynchronously, Jest needs to know when the code it is testing has completed, before it can move on to another test. Jest has several ways to handle this. -## Callbacks +## Promises + +Return a promise from your test, and Jest will wait for that promise to resolve. If the promise is rejected, the test will fail. + +For example, let's say that `fetchData` returns a promise that is supposed to resolve to the string `'peanut butter'`. We could test it with: + +```js +test('the data is peanut butter', () => { + return fetchData().then(data => { + expect(data).toBe('peanut butter'); + }); +}); +``` + +## Async/Await + +Alternatively, you can use `async` and `await` in your tests. To write an async test, use the `async` keyword in front of the function passed to `test`. For example, the same `fetchData` scenario can be tested with: + +```js +test('the data is peanut butter', async () => { + const data = await fetchData(); + expect(data).toBe('peanut butter'); +}); -The most common asynchronous pattern is callbacks. +test('the fetch fails with an error', async () => { + expect.assertions(1); + try { + await fetchData(); + } catch (e) { + expect(e).toMatch('error'); + } +}); +``` + +You can combine `async` and `await` with `.resolves` or `.rejects`. + +```js +test('the data is peanut butter', async () => { + await expect(fetchData()).resolves.toBe('peanut butter'); +}); + +test('the fetch fails with an error', async () => { + await expect(fetchData()).rejects.toMatch('error'); +}); +``` + +In these cases, `async` and `await` are effectively syntactic sugar for the same logic as the promises example uses. + +:::caution + +Be sure to return (or `await`) the promise - if you omit the `return`/`await` statement, your test will complete before the promise returned from `fetchData` resolves or rejects. + +::: + +If you expect a promise to be rejected, use the `.catch` method. Make sure to add `expect.assertions` to verify that a certain number of assertions are called. Otherwise, a fulfilled promise would not fail the test. + +```js +test('the fetch fails with an error', () => { + expect.assertions(1); + return fetchData().catch(e => expect(e).toMatch('error')); +}); +``` + +## Callbacks -For example, let's say that you have a `fetchData(callback)` function that fetches some data and calls `callback(data)` when it is complete. You want to test that this returned data is the string `'peanut butter'`. +If you don't use promises, you can use callbacks. For example, let's say that `fetchData`, instead of returning a promise, expects a callback, i.e. fetches some data and calls `callback(null, data)` when it is complete. You want to test that this returned data is the string `'peanut butter'`. By default, Jest tests complete once they reach the end of their execution. That means this test will _not_ work as intended: ```js // Don't do this! test('the data is peanut butter', () => { - function callback(data) { + function callback(error, data) { + if (error) { + throw error; + } expect(data).toBe('peanut butter'); } @@ -30,7 +94,11 @@ There is an alternate form of `test` that fixes this. Instead of putting the tes ```js test('the data is peanut butter', done => { - function callback(data) { + function callback(error, data) { + if (error) { + done(error); + return; + } try { expect(data).toBe('peanut butter'); done(); @@ -49,31 +117,6 @@ If the `expect` statement fails, it throws an error and `done()` is not called. _Note: `done()` should not be mixed with Promises as this tends to lead to memory leaks in your tests._ -## Promises - -If your code uses promises, there is a more straightforward way to handle asynchronous tests. Return a promise from your test, and Jest will wait for that promise to resolve. If the promise is rejected, the test will automatically fail. - -For example, let's say that `fetchData`, instead of using a callback, returns a promise that is supposed to resolve to the string `'peanut butter'`. We could test it with: - -```js -test('the data is peanut butter', () => { - return fetchData().then(data => { - expect(data).toBe('peanut butter'); - }); -}); -``` - -Be sure to return the promise - if you omit this `return` statement, your test will complete before the promise returned from `fetchData` resolves and then() has a chance to execute the callback. - -If you expect a promise to be rejected, use the `.catch` method. Make sure to add `expect.assertions` to verify that a certain number of assertions are called. Otherwise, a fulfilled promise would not fail the test. - -```js -test('the fetch fails with an error', () => { - expect.assertions(1); - return fetchData().catch(e => expect(e).toMatch('error')); -}); -``` - ## `.resolves` / `.rejects` You can also use the `.resolves` matcher in your expect statement, and Jest will wait for that promise to resolve. If the promise is rejected, the test will automatically fail. @@ -94,38 +137,4 @@ test('the fetch fails with an error', () => { }); ``` -## Async/Await - -Alternatively, you can use `async` and `await` in your tests. To write an async test, use the `async` keyword in front of the function passed to `test`. For example, the same `fetchData` scenario can be tested with: - -```js -test('the data is peanut butter', async () => { - const data = await fetchData(); - expect(data).toBe('peanut butter'); -}); - -test('the fetch fails with an error', async () => { - expect.assertions(1); - try { - await fetchData(); - } catch (e) { - expect(e).toMatch('error'); - } -}); -``` - -You can combine `async` and `await` with `.resolves` or `.rejects`. - -```js -test('the data is peanut butter', async () => { - await expect(fetchData()).resolves.toBe('peanut butter'); -}); - -test('the fetch fails with an error', async () => { - await expect(fetchData()).rejects.toMatch('error'); -}); -``` - -In these cases, `async` and `await` are effectively syntactic sugar for the same logic as the promises example uses. - None of these forms is particularly superior to the others, and you can mix and match them across a codebase or even in a single file. It just depends on which style you feel makes your tests simpler. diff --git a/website/versioned_docs/version-25.x/TestingAsyncCode.md b/website/versioned_docs/version-25.x/TestingAsyncCode.md index 432db44b3944..ef8762eb7d87 100644 --- a/website/versioned_docs/version-25.x/TestingAsyncCode.md +++ b/website/versioned_docs/version-25.x/TestingAsyncCode.md @@ -5,18 +5,82 @@ title: Testing Asynchronous Code It's common in JavaScript for code to run asynchronously. When you have code that runs asynchronously, Jest needs to know when the code it is testing has completed, before it can move on to another test. Jest has several ways to handle this. -## Callbacks +## Promises + +Return a promise from your test, and Jest will wait for that promise to resolve. If the promise is rejected, the test will fail. + +For example, let's say that `fetchData` returns a promise that is supposed to resolve to the string `'peanut butter'`. We could test it with: + +```js +test('the data is peanut butter', () => { + return fetchData().then(data => { + expect(data).toBe('peanut butter'); + }); +}); +``` + +## Async/Await + +Alternatively, you can use `async` and `await` in your tests. To write an async test, use the `async` keyword in front of the function passed to `test`. For example, the same `fetchData` scenario can be tested with: + +```js +test('the data is peanut butter', async () => { + const data = await fetchData(); + expect(data).toBe('peanut butter'); +}); -The most common asynchronous pattern is callbacks. +test('the fetch fails with an error', async () => { + expect.assertions(1); + try { + await fetchData(); + } catch (e) { + expect(e).toMatch('error'); + } +}); +``` + +You can combine `async` and `await` with `.resolves` or `.rejects`. + +```js +test('the data is peanut butter', async () => { + await expect(fetchData()).resolves.toBe('peanut butter'); +}); + +test('the fetch fails with an error', async () => { + await expect(fetchData()).rejects.toMatch('error'); +}); +``` + +In these cases, `async` and `await` are effectively syntactic sugar for the same logic as the promises example uses. + +:::caution + +Be sure to return (or `await`) the promise - if you omit the `return`/`await` statement, your test will complete before the promise returned from `fetchData` resolves or rejects. + +::: + +If you expect a promise to be rejected, use the `.catch` method. Make sure to add `expect.assertions` to verify that a certain number of assertions are called. Otherwise, a fulfilled promise would not fail the test. + +```js +test('the fetch fails with an error', () => { + expect.assertions(1); + return fetchData().catch(e => expect(e).toMatch('error')); +}); +``` + +## Callbacks -For example, let's say that you have a `fetchData(callback)` function that fetches some data and calls `callback(data)` when it is complete. You want to test that this returned data is the string `'peanut butter'`. +If you don't use promises, you can use callbacks. For example, let's say that `fetchData`, instead of returning a promise, expects a callback, i.e. fetches some data and calls `callback(null, data)` when it is complete. You want to test that this returned data is the string `'peanut butter'`. By default, Jest tests complete once they reach the end of their execution. That means this test will _not_ work as intended: ```js // Don't do this! test('the data is peanut butter', () => { - function callback(data) { + function callback(error, data) { + if (error) { + throw error; + } expect(data).toBe('peanut butter'); } @@ -30,7 +94,11 @@ There is an alternate form of `test` that fixes this. Instead of putting the tes ```js test('the data is peanut butter', done => { - function callback(data) { + function callback(error, data) { + if (error) { + done(error); + return; + } try { expect(data).toBe('peanut butter'); done(); @@ -49,31 +117,6 @@ If the `expect` statement fails, it throws an error and `done()` is not called. _Note: `done()` should not be mixed with Promises as this tends to lead to memory leaks in your tests._ -## Promises - -If your code uses promises, there is a more straightforward way to handle asynchronous tests. Return a promise from your test, and Jest will wait for that promise to resolve. If the promise is rejected, the test will automatically fail. - -For example, let's say that `fetchData`, instead of using a callback, returns a promise that is supposed to resolve to the string `'peanut butter'`. We could test it with: - -```js -test('the data is peanut butter', () => { - return fetchData().then(data => { - expect(data).toBe('peanut butter'); - }); -}); -``` - -Be sure to return the promise - if you omit this `return` statement, your test will complete before the promise returned from `fetchData` resolves and then() has a chance to execute the callback. - -If you expect a promise to be rejected, use the `.catch` method. Make sure to add `expect.assertions` to verify that a certain number of assertions are called. Otherwise, a fulfilled promise would not fail the test. - -```js -test('the fetch fails with an error', () => { - expect.assertions(1); - return fetchData().catch(e => expect(e).toMatch('error')); -}); -``` - ## `.resolves` / `.rejects` You can also use the `.resolves` matcher in your expect statement, and Jest will wait for that promise to resolve. If the promise is rejected, the test will automatically fail. @@ -94,38 +137,4 @@ test('the fetch fails with an error', () => { }); ``` -## Async/Await - -Alternatively, you can use `async` and `await` in your tests. To write an async test, use the `async` keyword in front of the function passed to `test`. For example, the same `fetchData` scenario can be tested with: - -```js -test('the data is peanut butter', async () => { - const data = await fetchData(); - expect(data).toBe('peanut butter'); -}); - -test('the fetch fails with an error', async () => { - expect.assertions(1); - try { - await fetchData(); - } catch (e) { - expect(e).toMatch('error'); - } -}); -``` - -You can combine `async` and `await` with `.resolves` or `.rejects`. - -```js -test('the data is peanut butter', async () => { - await expect(fetchData()).resolves.toBe('peanut butter'); -}); - -test('the fetch fails with an error', async () => { - await expect(fetchData()).rejects.toMatch('error'); -}); -``` - -In these cases, `async` and `await` are effectively syntactic sugar for the same logic as the promises example uses. - None of these forms is particularly superior to the others, and you can mix and match them across a codebase or even in a single file. It just depends on which style you feel makes your tests simpler. diff --git a/website/versioned_docs/version-26.x/TestingAsyncCode.md b/website/versioned_docs/version-26.x/TestingAsyncCode.md index 432db44b3944..ef8762eb7d87 100644 --- a/website/versioned_docs/version-26.x/TestingAsyncCode.md +++ b/website/versioned_docs/version-26.x/TestingAsyncCode.md @@ -5,18 +5,82 @@ title: Testing Asynchronous Code It's common in JavaScript for code to run asynchronously. When you have code that runs asynchronously, Jest needs to know when the code it is testing has completed, before it can move on to another test. Jest has several ways to handle this. -## Callbacks +## Promises + +Return a promise from your test, and Jest will wait for that promise to resolve. If the promise is rejected, the test will fail. + +For example, let's say that `fetchData` returns a promise that is supposed to resolve to the string `'peanut butter'`. We could test it with: + +```js +test('the data is peanut butter', () => { + return fetchData().then(data => { + expect(data).toBe('peanut butter'); + }); +}); +``` + +## Async/Await + +Alternatively, you can use `async` and `await` in your tests. To write an async test, use the `async` keyword in front of the function passed to `test`. For example, the same `fetchData` scenario can be tested with: + +```js +test('the data is peanut butter', async () => { + const data = await fetchData(); + expect(data).toBe('peanut butter'); +}); -The most common asynchronous pattern is callbacks. +test('the fetch fails with an error', async () => { + expect.assertions(1); + try { + await fetchData(); + } catch (e) { + expect(e).toMatch('error'); + } +}); +``` + +You can combine `async` and `await` with `.resolves` or `.rejects`. + +```js +test('the data is peanut butter', async () => { + await expect(fetchData()).resolves.toBe('peanut butter'); +}); + +test('the fetch fails with an error', async () => { + await expect(fetchData()).rejects.toMatch('error'); +}); +``` + +In these cases, `async` and `await` are effectively syntactic sugar for the same logic as the promises example uses. + +:::caution + +Be sure to return (or `await`) the promise - if you omit the `return`/`await` statement, your test will complete before the promise returned from `fetchData` resolves or rejects. + +::: + +If you expect a promise to be rejected, use the `.catch` method. Make sure to add `expect.assertions` to verify that a certain number of assertions are called. Otherwise, a fulfilled promise would not fail the test. + +```js +test('the fetch fails with an error', () => { + expect.assertions(1); + return fetchData().catch(e => expect(e).toMatch('error')); +}); +``` + +## Callbacks -For example, let's say that you have a `fetchData(callback)` function that fetches some data and calls `callback(data)` when it is complete. You want to test that this returned data is the string `'peanut butter'`. +If you don't use promises, you can use callbacks. For example, let's say that `fetchData`, instead of returning a promise, expects a callback, i.e. fetches some data and calls `callback(null, data)` when it is complete. You want to test that this returned data is the string `'peanut butter'`. By default, Jest tests complete once they reach the end of their execution. That means this test will _not_ work as intended: ```js // Don't do this! test('the data is peanut butter', () => { - function callback(data) { + function callback(error, data) { + if (error) { + throw error; + } expect(data).toBe('peanut butter'); } @@ -30,7 +94,11 @@ There is an alternate form of `test` that fixes this. Instead of putting the tes ```js test('the data is peanut butter', done => { - function callback(data) { + function callback(error, data) { + if (error) { + done(error); + return; + } try { expect(data).toBe('peanut butter'); done(); @@ -49,31 +117,6 @@ If the `expect` statement fails, it throws an error and `done()` is not called. _Note: `done()` should not be mixed with Promises as this tends to lead to memory leaks in your tests._ -## Promises - -If your code uses promises, there is a more straightforward way to handle asynchronous tests. Return a promise from your test, and Jest will wait for that promise to resolve. If the promise is rejected, the test will automatically fail. - -For example, let's say that `fetchData`, instead of using a callback, returns a promise that is supposed to resolve to the string `'peanut butter'`. We could test it with: - -```js -test('the data is peanut butter', () => { - return fetchData().then(data => { - expect(data).toBe('peanut butter'); - }); -}); -``` - -Be sure to return the promise - if you omit this `return` statement, your test will complete before the promise returned from `fetchData` resolves and then() has a chance to execute the callback. - -If you expect a promise to be rejected, use the `.catch` method. Make sure to add `expect.assertions` to verify that a certain number of assertions are called. Otherwise, a fulfilled promise would not fail the test. - -```js -test('the fetch fails with an error', () => { - expect.assertions(1); - return fetchData().catch(e => expect(e).toMatch('error')); -}); -``` - ## `.resolves` / `.rejects` You can also use the `.resolves` matcher in your expect statement, and Jest will wait for that promise to resolve. If the promise is rejected, the test will automatically fail. @@ -94,38 +137,4 @@ test('the fetch fails with an error', () => { }); ``` -## Async/Await - -Alternatively, you can use `async` and `await` in your tests. To write an async test, use the `async` keyword in front of the function passed to `test`. For example, the same `fetchData` scenario can be tested with: - -```js -test('the data is peanut butter', async () => { - const data = await fetchData(); - expect(data).toBe('peanut butter'); -}); - -test('the fetch fails with an error', async () => { - expect.assertions(1); - try { - await fetchData(); - } catch (e) { - expect(e).toMatch('error'); - } -}); -``` - -You can combine `async` and `await` with `.resolves` or `.rejects`. - -```js -test('the data is peanut butter', async () => { - await expect(fetchData()).resolves.toBe('peanut butter'); -}); - -test('the fetch fails with an error', async () => { - await expect(fetchData()).rejects.toMatch('error'); -}); -``` - -In these cases, `async` and `await` are effectively syntactic sugar for the same logic as the promises example uses. - None of these forms is particularly superior to the others, and you can mix and match them across a codebase or even in a single file. It just depends on which style you feel makes your tests simpler. diff --git a/website/versioned_docs/version-27.0/TestingAsyncCode.md b/website/versioned_docs/version-27.0/TestingAsyncCode.md index 432db44b3944..ef8762eb7d87 100644 --- a/website/versioned_docs/version-27.0/TestingAsyncCode.md +++ b/website/versioned_docs/version-27.0/TestingAsyncCode.md @@ -5,18 +5,82 @@ title: Testing Asynchronous Code It's common in JavaScript for code to run asynchronously. When you have code that runs asynchronously, Jest needs to know when the code it is testing has completed, before it can move on to another test. Jest has several ways to handle this. -## Callbacks +## Promises + +Return a promise from your test, and Jest will wait for that promise to resolve. If the promise is rejected, the test will fail. + +For example, let's say that `fetchData` returns a promise that is supposed to resolve to the string `'peanut butter'`. We could test it with: + +```js +test('the data is peanut butter', () => { + return fetchData().then(data => { + expect(data).toBe('peanut butter'); + }); +}); +``` + +## Async/Await + +Alternatively, you can use `async` and `await` in your tests. To write an async test, use the `async` keyword in front of the function passed to `test`. For example, the same `fetchData` scenario can be tested with: + +```js +test('the data is peanut butter', async () => { + const data = await fetchData(); + expect(data).toBe('peanut butter'); +}); -The most common asynchronous pattern is callbacks. +test('the fetch fails with an error', async () => { + expect.assertions(1); + try { + await fetchData(); + } catch (e) { + expect(e).toMatch('error'); + } +}); +``` + +You can combine `async` and `await` with `.resolves` or `.rejects`. + +```js +test('the data is peanut butter', async () => { + await expect(fetchData()).resolves.toBe('peanut butter'); +}); + +test('the fetch fails with an error', async () => { + await expect(fetchData()).rejects.toMatch('error'); +}); +``` + +In these cases, `async` and `await` are effectively syntactic sugar for the same logic as the promises example uses. + +:::caution + +Be sure to return (or `await`) the promise - if you omit the `return`/`await` statement, your test will complete before the promise returned from `fetchData` resolves or rejects. + +::: + +If you expect a promise to be rejected, use the `.catch` method. Make sure to add `expect.assertions` to verify that a certain number of assertions are called. Otherwise, a fulfilled promise would not fail the test. + +```js +test('the fetch fails with an error', () => { + expect.assertions(1); + return fetchData().catch(e => expect(e).toMatch('error')); +}); +``` + +## Callbacks -For example, let's say that you have a `fetchData(callback)` function that fetches some data and calls `callback(data)` when it is complete. You want to test that this returned data is the string `'peanut butter'`. +If you don't use promises, you can use callbacks. For example, let's say that `fetchData`, instead of returning a promise, expects a callback, i.e. fetches some data and calls `callback(null, data)` when it is complete. You want to test that this returned data is the string `'peanut butter'`. By default, Jest tests complete once they reach the end of their execution. That means this test will _not_ work as intended: ```js // Don't do this! test('the data is peanut butter', () => { - function callback(data) { + function callback(error, data) { + if (error) { + throw error; + } expect(data).toBe('peanut butter'); } @@ -30,7 +94,11 @@ There is an alternate form of `test` that fixes this. Instead of putting the tes ```js test('the data is peanut butter', done => { - function callback(data) { + function callback(error, data) { + if (error) { + done(error); + return; + } try { expect(data).toBe('peanut butter'); done(); @@ -49,31 +117,6 @@ If the `expect` statement fails, it throws an error and `done()` is not called. _Note: `done()` should not be mixed with Promises as this tends to lead to memory leaks in your tests._ -## Promises - -If your code uses promises, there is a more straightforward way to handle asynchronous tests. Return a promise from your test, and Jest will wait for that promise to resolve. If the promise is rejected, the test will automatically fail. - -For example, let's say that `fetchData`, instead of using a callback, returns a promise that is supposed to resolve to the string `'peanut butter'`. We could test it with: - -```js -test('the data is peanut butter', () => { - return fetchData().then(data => { - expect(data).toBe('peanut butter'); - }); -}); -``` - -Be sure to return the promise - if you omit this `return` statement, your test will complete before the promise returned from `fetchData` resolves and then() has a chance to execute the callback. - -If you expect a promise to be rejected, use the `.catch` method. Make sure to add `expect.assertions` to verify that a certain number of assertions are called. Otherwise, a fulfilled promise would not fail the test. - -```js -test('the fetch fails with an error', () => { - expect.assertions(1); - return fetchData().catch(e => expect(e).toMatch('error')); -}); -``` - ## `.resolves` / `.rejects` You can also use the `.resolves` matcher in your expect statement, and Jest will wait for that promise to resolve. If the promise is rejected, the test will automatically fail. @@ -94,38 +137,4 @@ test('the fetch fails with an error', () => { }); ``` -## Async/Await - -Alternatively, you can use `async` and `await` in your tests. To write an async test, use the `async` keyword in front of the function passed to `test`. For example, the same `fetchData` scenario can be tested with: - -```js -test('the data is peanut butter', async () => { - const data = await fetchData(); - expect(data).toBe('peanut butter'); -}); - -test('the fetch fails with an error', async () => { - expect.assertions(1); - try { - await fetchData(); - } catch (e) { - expect(e).toMatch('error'); - } -}); -``` - -You can combine `async` and `await` with `.resolves` or `.rejects`. - -```js -test('the data is peanut butter', async () => { - await expect(fetchData()).resolves.toBe('peanut butter'); -}); - -test('the fetch fails with an error', async () => { - await expect(fetchData()).rejects.toMatch('error'); -}); -``` - -In these cases, `async` and `await` are effectively syntactic sugar for the same logic as the promises example uses. - None of these forms is particularly superior to the others, and you can mix and match them across a codebase or even in a single file. It just depends on which style you feel makes your tests simpler. diff --git a/website/versioned_docs/version-27.1/TestingAsyncCode.md b/website/versioned_docs/version-27.1/TestingAsyncCode.md index 432db44b3944..ef8762eb7d87 100644 --- a/website/versioned_docs/version-27.1/TestingAsyncCode.md +++ b/website/versioned_docs/version-27.1/TestingAsyncCode.md @@ -5,18 +5,82 @@ title: Testing Asynchronous Code It's common in JavaScript for code to run asynchronously. When you have code that runs asynchronously, Jest needs to know when the code it is testing has completed, before it can move on to another test. Jest has several ways to handle this. -## Callbacks +## Promises + +Return a promise from your test, and Jest will wait for that promise to resolve. If the promise is rejected, the test will fail. + +For example, let's say that `fetchData` returns a promise that is supposed to resolve to the string `'peanut butter'`. We could test it with: + +```js +test('the data is peanut butter', () => { + return fetchData().then(data => { + expect(data).toBe('peanut butter'); + }); +}); +``` + +## Async/Await + +Alternatively, you can use `async` and `await` in your tests. To write an async test, use the `async` keyword in front of the function passed to `test`. For example, the same `fetchData` scenario can be tested with: + +```js +test('the data is peanut butter', async () => { + const data = await fetchData(); + expect(data).toBe('peanut butter'); +}); -The most common asynchronous pattern is callbacks. +test('the fetch fails with an error', async () => { + expect.assertions(1); + try { + await fetchData(); + } catch (e) { + expect(e).toMatch('error'); + } +}); +``` + +You can combine `async` and `await` with `.resolves` or `.rejects`. + +```js +test('the data is peanut butter', async () => { + await expect(fetchData()).resolves.toBe('peanut butter'); +}); + +test('the fetch fails with an error', async () => { + await expect(fetchData()).rejects.toMatch('error'); +}); +``` + +In these cases, `async` and `await` are effectively syntactic sugar for the same logic as the promises example uses. + +:::caution + +Be sure to return (or `await`) the promise - if you omit the `return`/`await` statement, your test will complete before the promise returned from `fetchData` resolves or rejects. + +::: + +If you expect a promise to be rejected, use the `.catch` method. Make sure to add `expect.assertions` to verify that a certain number of assertions are called. Otherwise, a fulfilled promise would not fail the test. + +```js +test('the fetch fails with an error', () => { + expect.assertions(1); + return fetchData().catch(e => expect(e).toMatch('error')); +}); +``` + +## Callbacks -For example, let's say that you have a `fetchData(callback)` function that fetches some data and calls `callback(data)` when it is complete. You want to test that this returned data is the string `'peanut butter'`. +If you don't use promises, you can use callbacks. For example, let's say that `fetchData`, instead of returning a promise, expects a callback, i.e. fetches some data and calls `callback(null, data)` when it is complete. You want to test that this returned data is the string `'peanut butter'`. By default, Jest tests complete once they reach the end of their execution. That means this test will _not_ work as intended: ```js // Don't do this! test('the data is peanut butter', () => { - function callback(data) { + function callback(error, data) { + if (error) { + throw error; + } expect(data).toBe('peanut butter'); } @@ -30,7 +94,11 @@ There is an alternate form of `test` that fixes this. Instead of putting the tes ```js test('the data is peanut butter', done => { - function callback(data) { + function callback(error, data) { + if (error) { + done(error); + return; + } try { expect(data).toBe('peanut butter'); done(); @@ -49,31 +117,6 @@ If the `expect` statement fails, it throws an error and `done()` is not called. _Note: `done()` should not be mixed with Promises as this tends to lead to memory leaks in your tests._ -## Promises - -If your code uses promises, there is a more straightforward way to handle asynchronous tests. Return a promise from your test, and Jest will wait for that promise to resolve. If the promise is rejected, the test will automatically fail. - -For example, let's say that `fetchData`, instead of using a callback, returns a promise that is supposed to resolve to the string `'peanut butter'`. We could test it with: - -```js -test('the data is peanut butter', () => { - return fetchData().then(data => { - expect(data).toBe('peanut butter'); - }); -}); -``` - -Be sure to return the promise - if you omit this `return` statement, your test will complete before the promise returned from `fetchData` resolves and then() has a chance to execute the callback. - -If you expect a promise to be rejected, use the `.catch` method. Make sure to add `expect.assertions` to verify that a certain number of assertions are called. Otherwise, a fulfilled promise would not fail the test. - -```js -test('the fetch fails with an error', () => { - expect.assertions(1); - return fetchData().catch(e => expect(e).toMatch('error')); -}); -``` - ## `.resolves` / `.rejects` You can also use the `.resolves` matcher in your expect statement, and Jest will wait for that promise to resolve. If the promise is rejected, the test will automatically fail. @@ -94,38 +137,4 @@ test('the fetch fails with an error', () => { }); ``` -## Async/Await - -Alternatively, you can use `async` and `await` in your tests. To write an async test, use the `async` keyword in front of the function passed to `test`. For example, the same `fetchData` scenario can be tested with: - -```js -test('the data is peanut butter', async () => { - const data = await fetchData(); - expect(data).toBe('peanut butter'); -}); - -test('the fetch fails with an error', async () => { - expect.assertions(1); - try { - await fetchData(); - } catch (e) { - expect(e).toMatch('error'); - } -}); -``` - -You can combine `async` and `await` with `.resolves` or `.rejects`. - -```js -test('the data is peanut butter', async () => { - await expect(fetchData()).resolves.toBe('peanut butter'); -}); - -test('the fetch fails with an error', async () => { - await expect(fetchData()).rejects.toMatch('error'); -}); -``` - -In these cases, `async` and `await` are effectively syntactic sugar for the same logic as the promises example uses. - None of these forms is particularly superior to the others, and you can mix and match them across a codebase or even in a single file. It just depends on which style you feel makes your tests simpler. diff --git a/website/versioned_docs/version-27.2/TestingAsyncCode.md b/website/versioned_docs/version-27.2/TestingAsyncCode.md index 432db44b3944..ef8762eb7d87 100644 --- a/website/versioned_docs/version-27.2/TestingAsyncCode.md +++ b/website/versioned_docs/version-27.2/TestingAsyncCode.md @@ -5,18 +5,82 @@ title: Testing Asynchronous Code It's common in JavaScript for code to run asynchronously. When you have code that runs asynchronously, Jest needs to know when the code it is testing has completed, before it can move on to another test. Jest has several ways to handle this. -## Callbacks +## Promises + +Return a promise from your test, and Jest will wait for that promise to resolve. If the promise is rejected, the test will fail. + +For example, let's say that `fetchData` returns a promise that is supposed to resolve to the string `'peanut butter'`. We could test it with: + +```js +test('the data is peanut butter', () => { + return fetchData().then(data => { + expect(data).toBe('peanut butter'); + }); +}); +``` + +## Async/Await + +Alternatively, you can use `async` and `await` in your tests. To write an async test, use the `async` keyword in front of the function passed to `test`. For example, the same `fetchData` scenario can be tested with: + +```js +test('the data is peanut butter', async () => { + const data = await fetchData(); + expect(data).toBe('peanut butter'); +}); -The most common asynchronous pattern is callbacks. +test('the fetch fails with an error', async () => { + expect.assertions(1); + try { + await fetchData(); + } catch (e) { + expect(e).toMatch('error'); + } +}); +``` + +You can combine `async` and `await` with `.resolves` or `.rejects`. + +```js +test('the data is peanut butter', async () => { + await expect(fetchData()).resolves.toBe('peanut butter'); +}); + +test('the fetch fails with an error', async () => { + await expect(fetchData()).rejects.toMatch('error'); +}); +``` + +In these cases, `async` and `await` are effectively syntactic sugar for the same logic as the promises example uses. + +:::caution + +Be sure to return (or `await`) the promise - if you omit the `return`/`await` statement, your test will complete before the promise returned from `fetchData` resolves or rejects. + +::: + +If you expect a promise to be rejected, use the `.catch` method. Make sure to add `expect.assertions` to verify that a certain number of assertions are called. Otherwise, a fulfilled promise would not fail the test. + +```js +test('the fetch fails with an error', () => { + expect.assertions(1); + return fetchData().catch(e => expect(e).toMatch('error')); +}); +``` + +## Callbacks -For example, let's say that you have a `fetchData(callback)` function that fetches some data and calls `callback(data)` when it is complete. You want to test that this returned data is the string `'peanut butter'`. +If you don't use promises, you can use callbacks. For example, let's say that `fetchData`, instead of returning a promise, expects a callback, i.e. fetches some data and calls `callback(null, data)` when it is complete. You want to test that this returned data is the string `'peanut butter'`. By default, Jest tests complete once they reach the end of their execution. That means this test will _not_ work as intended: ```js // Don't do this! test('the data is peanut butter', () => { - function callback(data) { + function callback(error, data) { + if (error) { + throw error; + } expect(data).toBe('peanut butter'); } @@ -30,7 +94,11 @@ There is an alternate form of `test` that fixes this. Instead of putting the tes ```js test('the data is peanut butter', done => { - function callback(data) { + function callback(error, data) { + if (error) { + done(error); + return; + } try { expect(data).toBe('peanut butter'); done(); @@ -49,31 +117,6 @@ If the `expect` statement fails, it throws an error and `done()` is not called. _Note: `done()` should not be mixed with Promises as this tends to lead to memory leaks in your tests._ -## Promises - -If your code uses promises, there is a more straightforward way to handle asynchronous tests. Return a promise from your test, and Jest will wait for that promise to resolve. If the promise is rejected, the test will automatically fail. - -For example, let's say that `fetchData`, instead of using a callback, returns a promise that is supposed to resolve to the string `'peanut butter'`. We could test it with: - -```js -test('the data is peanut butter', () => { - return fetchData().then(data => { - expect(data).toBe('peanut butter'); - }); -}); -``` - -Be sure to return the promise - if you omit this `return` statement, your test will complete before the promise returned from `fetchData` resolves and then() has a chance to execute the callback. - -If you expect a promise to be rejected, use the `.catch` method. Make sure to add `expect.assertions` to verify that a certain number of assertions are called. Otherwise, a fulfilled promise would not fail the test. - -```js -test('the fetch fails with an error', () => { - expect.assertions(1); - return fetchData().catch(e => expect(e).toMatch('error')); -}); -``` - ## `.resolves` / `.rejects` You can also use the `.resolves` matcher in your expect statement, and Jest will wait for that promise to resolve. If the promise is rejected, the test will automatically fail. @@ -94,38 +137,4 @@ test('the fetch fails with an error', () => { }); ``` -## Async/Await - -Alternatively, you can use `async` and `await` in your tests. To write an async test, use the `async` keyword in front of the function passed to `test`. For example, the same `fetchData` scenario can be tested with: - -```js -test('the data is peanut butter', async () => { - const data = await fetchData(); - expect(data).toBe('peanut butter'); -}); - -test('the fetch fails with an error', async () => { - expect.assertions(1); - try { - await fetchData(); - } catch (e) { - expect(e).toMatch('error'); - } -}); -``` - -You can combine `async` and `await` with `.resolves` or `.rejects`. - -```js -test('the data is peanut butter', async () => { - await expect(fetchData()).resolves.toBe('peanut butter'); -}); - -test('the fetch fails with an error', async () => { - await expect(fetchData()).rejects.toMatch('error'); -}); -``` - -In these cases, `async` and `await` are effectively syntactic sugar for the same logic as the promises example uses. - None of these forms is particularly superior to the others, and you can mix and match them across a codebase or even in a single file. It just depends on which style you feel makes your tests simpler. diff --git a/website/versioned_docs/version-27.4/TestingAsyncCode.md b/website/versioned_docs/version-27.4/TestingAsyncCode.md index 432db44b3944..ef8762eb7d87 100644 --- a/website/versioned_docs/version-27.4/TestingAsyncCode.md +++ b/website/versioned_docs/version-27.4/TestingAsyncCode.md @@ -5,18 +5,82 @@ title: Testing Asynchronous Code It's common in JavaScript for code to run asynchronously. When you have code that runs asynchronously, Jest needs to know when the code it is testing has completed, before it can move on to another test. Jest has several ways to handle this. -## Callbacks +## Promises + +Return a promise from your test, and Jest will wait for that promise to resolve. If the promise is rejected, the test will fail. + +For example, let's say that `fetchData` returns a promise that is supposed to resolve to the string `'peanut butter'`. We could test it with: + +```js +test('the data is peanut butter', () => { + return fetchData().then(data => { + expect(data).toBe('peanut butter'); + }); +}); +``` + +## Async/Await + +Alternatively, you can use `async` and `await` in your tests. To write an async test, use the `async` keyword in front of the function passed to `test`. For example, the same `fetchData` scenario can be tested with: + +```js +test('the data is peanut butter', async () => { + const data = await fetchData(); + expect(data).toBe('peanut butter'); +}); -The most common asynchronous pattern is callbacks. +test('the fetch fails with an error', async () => { + expect.assertions(1); + try { + await fetchData(); + } catch (e) { + expect(e).toMatch('error'); + } +}); +``` + +You can combine `async` and `await` with `.resolves` or `.rejects`. + +```js +test('the data is peanut butter', async () => { + await expect(fetchData()).resolves.toBe('peanut butter'); +}); + +test('the fetch fails with an error', async () => { + await expect(fetchData()).rejects.toMatch('error'); +}); +``` + +In these cases, `async` and `await` are effectively syntactic sugar for the same logic as the promises example uses. + +:::caution + +Be sure to return (or `await`) the promise - if you omit the `return`/`await` statement, your test will complete before the promise returned from `fetchData` resolves or rejects. + +::: + +If you expect a promise to be rejected, use the `.catch` method. Make sure to add `expect.assertions` to verify that a certain number of assertions are called. Otherwise, a fulfilled promise would not fail the test. + +```js +test('the fetch fails with an error', () => { + expect.assertions(1); + return fetchData().catch(e => expect(e).toMatch('error')); +}); +``` + +## Callbacks -For example, let's say that you have a `fetchData(callback)` function that fetches some data and calls `callback(data)` when it is complete. You want to test that this returned data is the string `'peanut butter'`. +If you don't use promises, you can use callbacks. For example, let's say that `fetchData`, instead of returning a promise, expects a callback, i.e. fetches some data and calls `callback(null, data)` when it is complete. You want to test that this returned data is the string `'peanut butter'`. By default, Jest tests complete once they reach the end of their execution. That means this test will _not_ work as intended: ```js // Don't do this! test('the data is peanut butter', () => { - function callback(data) { + function callback(error, data) { + if (error) { + throw error; + } expect(data).toBe('peanut butter'); } @@ -30,7 +94,11 @@ There is an alternate form of `test` that fixes this. Instead of putting the tes ```js test('the data is peanut butter', done => { - function callback(data) { + function callback(error, data) { + if (error) { + done(error); + return; + } try { expect(data).toBe('peanut butter'); done(); @@ -49,31 +117,6 @@ If the `expect` statement fails, it throws an error and `done()` is not called. _Note: `done()` should not be mixed with Promises as this tends to lead to memory leaks in your tests._ -## Promises - -If your code uses promises, there is a more straightforward way to handle asynchronous tests. Return a promise from your test, and Jest will wait for that promise to resolve. If the promise is rejected, the test will automatically fail. - -For example, let's say that `fetchData`, instead of using a callback, returns a promise that is supposed to resolve to the string `'peanut butter'`. We could test it with: - -```js -test('the data is peanut butter', () => { - return fetchData().then(data => { - expect(data).toBe('peanut butter'); - }); -}); -``` - -Be sure to return the promise - if you omit this `return` statement, your test will complete before the promise returned from `fetchData` resolves and then() has a chance to execute the callback. - -If you expect a promise to be rejected, use the `.catch` method. Make sure to add `expect.assertions` to verify that a certain number of assertions are called. Otherwise, a fulfilled promise would not fail the test. - -```js -test('the fetch fails with an error', () => { - expect.assertions(1); - return fetchData().catch(e => expect(e).toMatch('error')); -}); -``` - ## `.resolves` / `.rejects` You can also use the `.resolves` matcher in your expect statement, and Jest will wait for that promise to resolve. If the promise is rejected, the test will automatically fail. @@ -94,38 +137,4 @@ test('the fetch fails with an error', () => { }); ``` -## Async/Await - -Alternatively, you can use `async` and `await` in your tests. To write an async test, use the `async` keyword in front of the function passed to `test`. For example, the same `fetchData` scenario can be tested with: - -```js -test('the data is peanut butter', async () => { - const data = await fetchData(); - expect(data).toBe('peanut butter'); -}); - -test('the fetch fails with an error', async () => { - expect.assertions(1); - try { - await fetchData(); - } catch (e) { - expect(e).toMatch('error'); - } -}); -``` - -You can combine `async` and `await` with `.resolves` or `.rejects`. - -```js -test('the data is peanut butter', async () => { - await expect(fetchData()).resolves.toBe('peanut butter'); -}); - -test('the fetch fails with an error', async () => { - await expect(fetchData()).rejects.toMatch('error'); -}); -``` - -In these cases, `async` and `await` are effectively syntactic sugar for the same logic as the promises example uses. - None of these forms is particularly superior to the others, and you can mix and match them across a codebase or even in a single file. It just depends on which style you feel makes your tests simpler. diff --git a/website/versioned_docs/version-27.5/TestingAsyncCode.md b/website/versioned_docs/version-27.5/TestingAsyncCode.md index 5f7e7132f0e6..ef8762eb7d87 100644 --- a/website/versioned_docs/version-27.5/TestingAsyncCode.md +++ b/website/versioned_docs/version-27.5/TestingAsyncCode.md @@ -55,7 +55,7 @@ In these cases, `async` and `await` are effectively syntactic sugar for the same :::caution -Be sure to return (or `await`) the promise - if you omit the `return` statement, your test will complete before the promise returned from `fetchData` resolves and `then()` has a chance to execute the callback. +Be sure to return (or `await`) the promise - if you omit the `return`/`await` statement, your test will complete before the promise returned from `fetchData` resolves or rejects. ::: @@ -70,14 +70,17 @@ test('the fetch fails with an error', () => { ## Callbacks -For example, let's say that `fetchData`, instead of returning a promise, expects a callback, i.e. fetches some data and calls `callback(data)` when it is complete. You want to test that this returned data is the string `'peanut butter'`. +If you don't use promises, you can use callbacks. For example, let's say that `fetchData`, instead of returning a promise, expects a callback, i.e. fetches some data and calls `callback(null, data)` when it is complete. You want to test that this returned data is the string `'peanut butter'`. By default, Jest tests complete once they reach the end of their execution. That means this test will _not_ work as intended: ```js // Don't do this! test('the data is peanut butter', () => { - function callback(data) { + function callback(error, data) { + if (error) { + throw error; + } expect(data).toBe('peanut butter'); } @@ -91,7 +94,11 @@ There is an alternate form of `test` that fixes this. Instead of putting the tes ```js test('the data is peanut butter', done => { - function callback(data) { + function callback(error, data) { + if (error) { + done(error); + return; + } try { expect(data).toBe('peanut butter'); done();