From 02b1bf854f7a45843f040a599d6c2e2aac60261c Mon Sep 17 00:00:00 2001 From: Dirk-Jan Rutten Date: Sat, 18 Mar 2017 13:22:05 +0100 Subject: [PATCH 1/4] Updated expect API docs with .resolves and .rejects --- docs/ExpectAPI.md | 48 ++++++++++++++++++++++++++++++++++++++++ docs/TestingAsyncCode.md | 9 +++----- docs/TutorialAsync.md | 33 +++++++++------------------ 3 files changed, 61 insertions(+), 29 deletions(-) diff --git a/docs/ExpectAPI.md b/docs/ExpectAPI.md index bf0e2bc60028..54f3f0737be2 100644 --- a/docs/ExpectAPI.md +++ b/docs/ExpectAPI.md @@ -286,6 +286,54 @@ test('the best flavor is not coconut', () => { }); ``` +### `.resolves` + +If your code uses Promises, use the `.resolves` keyword, and Jest will wait for the Promise to resolve and then run an assertion on the resulting value. + +For example, this code tests that the Promise returned by `fetchData()` resolves and that the resulting value is peanut butter: + +```js +test('fetchData() resolves and is peanut butter', () => { + //make sure to add a return statement + return expect(fetchData()).resolves.toBe('peanut butter'); +}); +``` + +Alternatively, you can use `async/await` in combination with `.resolves`: + +```js +test('fetchData() resolves and is peanut butter', async () => { + await expect(fetchData()).resolves.toBe('peanut butter'); + await expect(fetchData()).resolves.not.toBe('coconut'); +}); +``` + +### `.rejects` + +If your code uses Promises, use the `.rejects` keyword, and Jest will wait for that Promise to reject and then run an assertion on the resulting value. + +For example, this code tests that the Promise returned by `fetchData()` rejects and that the resulting value is an error: + +```js +test('fetchData() rejects to be error', () => { + //make sure to add a return statement + return expect(fetchData()).rejects.toEqual({ + error: "User not found" + }); +}); +``` + +Alternatively, you can use `async/await` in combination with `.rejects`: + +```js +test('fetchData() rejects to be error', async () => { + await expect(fetchData()).rejects.toEqual({ + error: "User not found" + }); + await expect(fetchData()).rejects.not.toBe("Mark"); +}); +``` + ### `.toBe(value)` `toBe` just checks that a value is what you expect. It uses `===` to check diff --git a/docs/TestingAsyncCode.md b/docs/TestingAsyncCode.md index 0cffcd5f451c..fdcead35916e 100644 --- a/docs/TestingAsyncCode.md +++ b/docs/TestingAsyncCode.md @@ -48,15 +48,13 @@ If `done()` is never called, the test will fail, which is what you want to happe ### Promises -If your code uses promises, there is a simpler way to handle asynchronous tests. Just 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. +If your code uses promises, there is a simpler way to handle asynchronous tests. Just use the `resolves` keyword in your expect statement, 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'); - }); + return expect(fetchData()).resolves.toBe('peanut butter'); }); ``` @@ -68,8 +66,7 @@ If your code uses `async` and `await`, you can use these in your tests as well. ```js test('the data is peanut butter', async () => { - const data = await fetchData(); - expect(data).toBe('peanut butter'); + await expect(fetchData()).resolves.toBe('peanut butter'); }); ``` diff --git a/docs/TutorialAsync.md b/docs/TutorialAsync.md index 5de60158dd74..78cec758f153 100644 --- a/docs/TutorialAsync.md +++ b/docs/TutorialAsync.md @@ -68,7 +68,7 @@ export default function request(url) { } ``` -Now let's write a test for our async functionality. +Now let's write a test for our async functionality. Using the `resolves` keyword ```js // __tests__/user-test.js jest.mock('../request'); @@ -77,8 +77,7 @@ import * as user from '../user'; // The promise that is being tested should be returned. it('works with promises', () => { - return user.getUserName(5) - .then(name => expect(name).toEqual('Paul')); + return expect(user.getUserName(5)).resolves.toEqual('Paul')); }); ``` @@ -94,8 +93,7 @@ how you'd write the same example from before: ```js // async/await can also be used. it('works with async/await', async () => { - const userName = await user.getUserName(4); - expect(userName).toEqual('Mark'); + await expect(user.getUserName(4)).resolves.toEqual('Mark'); }); ``` @@ -106,32 +104,21 @@ and enable the feature in your `.babelrc` file. ### Error handling -Errors can be handled in the standard JavaScript way: Either using `.catch()` -directly on a Promise or through `try-catch` when using async/await. Note that -if a Promise throws and the error is not handled, the test will fail. `expect.assertion(1)` makes sure that expectation was checked once. In this example it will fail if promise was resolved without throwing. +Errors can be handled using the keyword `rejects` in your expect statement. This will verify that the promise rejects and perform an assertion on the resulting error. ```js // Testing for async errors can be done using `catch`. it('tests error with promises', () => { - // to be sure that `Promise` rejected and `expect` has been called once - expect.assertions(1); - - return user.getUserName(3) - .catch(e => expect(e).toEqual({ - error: 'User with 3 not found.', - })); + return expect(user.getUserName(3)).rejects.toEqual({ + error: 'User with 3 not found.', + }); }); // Or try-catch. it('tests error with async/await', async () => { - // to be sure that `await` throws error and `expect` has been called once - expect.assertions(1); - - try { - await user.getUserName(2); - } catch (object) { - expect(object.error).toEqual('User with 2 not found.'); - } + await expect(user.getUserName(3)).rejects.toEqual({ + error: 'User with 3 not found.', + }); }); ``` From 668725c30f06c68a60bfde94fb56b45ea7721d54 Mon Sep 17 00:00:00 2001 From: Dirk-Jan Rutten Date: Sat, 18 Mar 2017 17:43:30 +0100 Subject: [PATCH 2/4] Fixed linter errors in the docs. --- docs/ExpectAPI.md | 6 +++--- docs/TutorialAsync.md | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/ExpectAPI.md b/docs/ExpectAPI.md index 54f3f0737be2..5b063106e744 100644 --- a/docs/ExpectAPI.md +++ b/docs/ExpectAPI.md @@ -318,7 +318,7 @@ For example, this code tests that the Promise returned by `fetchData()` rejects test('fetchData() rejects to be error', () => { //make sure to add a return statement return expect(fetchData()).rejects.toEqual({ - error: "User not found" + error: 'User not found', }); }); ``` @@ -328,9 +328,9 @@ Alternatively, you can use `async/await` in combination with `.rejects`: ```js test('fetchData() rejects to be error', async () => { await expect(fetchData()).rejects.toEqual({ - error: "User not found" + error: 'User not found', }); - await expect(fetchData()).rejects.not.toBe("Mark"); + await expect(fetchData()).rejects.not.toBe('Mark'); }); ``` diff --git a/docs/TutorialAsync.md b/docs/TutorialAsync.md index 78cec758f153..68f62bec03d3 100644 --- a/docs/TutorialAsync.md +++ b/docs/TutorialAsync.md @@ -68,7 +68,7 @@ export default function request(url) { } ``` -Now let's write a test for our async functionality. Using the `resolves` keyword +Now let's write a test for our async functionality. Using the `resolves` keyword ```js // __tests__/user-test.js jest.mock('../request'); @@ -77,7 +77,7 @@ import * as user from '../user'; // The promise that is being tested should be returned. it('works with promises', () => { - return expect(user.getUserName(5)).resolves.toEqual('Paul')); + return expect(user.getUserName(5)).resolves.toEqual('Paul'); }); ``` From 797af540890e6ea4f906beb3f1fb7f9169edb711 Mon Sep 17 00:00:00 2001 From: Dirk-Jan Rutten Date: Sun, 19 Mar 2017 13:35:07 +0100 Subject: [PATCH 3/4] added API availability status --- docs/ExpectAPI.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/ExpectAPI.md b/docs/ExpectAPI.md index 5b063106e744..7565f2f11165 100644 --- a/docs/ExpectAPI.md +++ b/docs/ExpectAPI.md @@ -288,6 +288,8 @@ test('the best flavor is not coconut', () => { ### `.resolves` +##### available in Jest **20.0.0+** + If your code uses Promises, use the `.resolves` keyword, and Jest will wait for the Promise to resolve and then run an assertion on the resulting value. For example, this code tests that the Promise returned by `fetchData()` resolves and that the resulting value is peanut butter: @@ -310,6 +312,8 @@ test('fetchData() resolves and is peanut butter', async () => { ### `.rejects` +##### available in Jest **20.0.0+** + If your code uses Promises, use the `.rejects` keyword, and Jest will wait for that Promise to reject and then run an assertion on the resulting value. For example, this code tests that the Promise returned by `fetchData()` rejects and that the resulting value is an error: From 1187ffbfa1d3addc0529ce7f317d0a1f9c8c9003 Mon Sep 17 00:00:00 2001 From: Dirk-Jan Rutten Date: Tue, 21 Mar 2017 20:16:01 +0100 Subject: [PATCH 4/4] minor styling issue fix --- docs/ExpectAPI.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/ExpectAPI.md b/docs/ExpectAPI.md index 7565f2f11165..d6d2e6ab38ea 100644 --- a/docs/ExpectAPI.md +++ b/docs/ExpectAPI.md @@ -296,7 +296,7 @@ For example, this code tests that the Promise returned by `fetchData()` resolves ```js test('fetchData() resolves and is peanut butter', () => { - //make sure to add a return statement + // make sure to add a return statement return expect(fetchData()).resolves.toBe('peanut butter'); }); ``` @@ -320,7 +320,7 @@ For example, this code tests that the Promise returned by `fetchData()` rejects ```js test('fetchData() rejects to be error', () => { - //make sure to add a return statement + // make sure to add a return statement return expect(fetchData()).rejects.toEqual({ error: 'User not found', });