Skip to content

Commit

Permalink
[expect] Improve mock "return" matchers to properly handle calls that…
Browse files Browse the repository at this point in the history
… throw (#6172)

* Improve mock "return" matchers to properly handle calls that throw

* Fix unit test that was broken because expect().toThrow() does not
proeprly detect a thrown value of undefined.

* update CHANGELOG

* Fix comment typo

* Simplify structure of how mock function results are maintained.
  • Loading branch information
UselessPickles authored and cpojer committed May 22, 2018
1 parent 9867e16 commit f55f3d8
Show file tree
Hide file tree
Showing 8 changed files with 675 additions and 98 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@
([#6181](https://github.com/facebook/jest/pull/6181))
* `[expect]` Include custom mock names in error messages
([#6199](https://github.com/facebook/jest/pull/6199))
* `[expect]` Improve return matchers
([#6172](https://github.com/facebook/jest/pull/6172))

### Fixes

Expand Down
23 changes: 16 additions & 7 deletions docs/ExpectAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -683,8 +683,9 @@ Note: the nth argument must be positive integer starting from 1.
Also under the alias: `.toReturn()`

If you have a mock function, you can use `.toHaveReturned` to test that the mock
function returned a value. For example, let's say you have a mock `drink` that
returns `true`. You can write:
function successfully returned (i.e., did not throw an error) at least one time.
For example, let's say you have a mock `drink` that returns `true`. You can
write:

```js
test('drinks returns', () => {
Expand All @@ -700,9 +701,13 @@ test('drinks returns', () => {

Also under the alias: `.toReturnTimes(number)`

Use `.toHaveReturnedTimes` to ensure that a mock function returned an exact
number of times. For example, let's say you have a mock `drink` that returns
`true`. You can write:
Use `.toHaveReturnedTimes` to ensure that a mock function returned successfully
(i.e., did not throw an error) an exact number of times. Any calls to the mock
function that throw an error are not counted toward the number of times the
function returned.

For example, let's say you have a mock `drink` that returns `true`. You can
write:

```js
test('drink returns twice', () => {
Expand Down Expand Up @@ -741,7 +746,9 @@ test('drink returns La Croix', () => {
Also under the alias: `.lastReturnedWith(value)`

Use `.toHaveLastReturnedWith` to test the specific value that a mock function
last returned.
last returned. If the last call to the mock function threw an error, then this
matcher will fail no matter what value you provided as the expected return
value.

For example, let's say you have a mock `drink` that returns the name of the
beverage that was consumed. You can write:
Expand All @@ -764,7 +771,9 @@ test('drink returns La Croix (Orange) last', () => {
Also under the alias: `.nthReturnedWith(nthCall, value)`

Use `.toHaveNthReturnedWith` to test the specific value that a mock function
returned for the nth call.
returned for the nth call. If the nth call to the mock function threw an error,
then this matcher will fail no matter what value you provided as the expected
return value.

For example, let's say you have a mock `drink` that returns the name of the
beverage that was consumed. You can write:
Expand Down
50 changes: 26 additions & 24 deletions docs/MockFunctionAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ Returns the mock name string set by calling `mockFn.mockName(value)`.

### `mockFn.mock.calls`

An array that represents all calls that have been made into this mock function.
Each call is represented by an array of arguments that were passed during the
call.
An array containing the call arguments of all calls that have been made to this
mock function. Each item in the array is an array of arguments that were passed
during the call.

For example: A mock function `f` that has been called twice, with the arguments
`f('arg1', 'arg2')`, and then with the arguments `f('arg3', 'arg4')`, would have
Expand All @@ -34,33 +34,35 @@ a `mock.calls` array that looks like this:
[['arg1', 'arg2'], ['arg3', 'arg4']];
```

### `mockFn.mock.returnValues`
### `mockFn.mock.results`

An array containing values that have been returned by all calls to this mock
function. For any call to the mock that throws an error, a value of `undefined`
will be stored in `mock.returnValues`.
An array containing the results of all calls that have been made to this mock
function. Each entry in this array is an object containing a boolean `isThrow`
property, and a `value` property. `isThrow` is true if the call terminated due
to a `throw`, or false if the the call returned normally. The `value` property
contains the value that was thrown or returned.

For example: A mock function `f` that has been called three times, returning
`result1`, throwing an error, and then returning `result2`, would have a
`mock.returnValues` array that looks like this:
`mock.results` array that looks like this:

```js
['result1', undefined, 'result2'];
```

### `mockFn.mock.thrownErrors`

An array containing errors that have been thrown by all calls to this mock
function.

For example: A mock function `f` that has been called twice, throwing an
`Error`, and then executing successfully without an error, would have the
following `mock.thrownErrors` array:

```js
f.mock.thrownErrors.length === 2; // true
f.mock.thrownErrors[0] instanceof Error; // true
f.mock.thrownErrors[1] === undefined; // true
[
{
isThrow: false,
value: 'result1',
},
{
isThrow: true,
value: {
/* Error instance */
},
},
{
isThrow: false,
value: 'result2',
},
];
```

### `mockFn.mock.instances`
Expand Down
Loading

0 comments on commit f55f3d8

Please sign in to comment.