Skip to content

Commit 5f71018

Browse files
authored
feat!: add promise-based return assertions, do not auto-resolve returned promises (#5749)
1 parent 48c502f commit 5f71018

File tree

11 files changed

+446
-102
lines changed

11 files changed

+446
-102
lines changed

docs/api/expect.md

+117-2
Original file line numberDiff line numberDiff line change
@@ -954,7 +954,7 @@ test('spy function returned a value', () => {
954954

955955
- **Type**: `(amount: number) => Awaitable<void>`
956956

957-
This assertion checks if a function has successfully returned a value exact amount of times (i.e., did not throw an error). Requires a spy function to be passed to `expect`.
957+
This assertion checks if a function has successfully returned a value an exact amount of times (i.e., did not throw an error). Requires a spy function to be passed to `expect`.
958958

959959
```ts twoslash
960960
import { expect, test, vi } from 'vitest'
@@ -991,7 +991,7 @@ test('spy function returns a product', () => {
991991

992992
- **Type**: `(returnValue: any) => Awaitable<void>`
993993

994-
You can call this assertion to check if a function has successfully returned a value with certain parameters on its last invoking. Requires a spy function to be passed to `expect`.
994+
You can call this assertion to check if a function has successfully returned a certain value when it was last invoked. Requires a spy function to be passed to `expect`.
995995

996996
```ts twoslash
997997
import { expect, test, vi } from 'vitest'
@@ -1025,6 +1025,121 @@ test('spy function returns bananas on second call', () => {
10251025
})
10261026
```
10271027

1028+
## toHaveResolved
1029+
1030+
- **Type**: `() => Awaitable<void>`
1031+
1032+
This assertion checks if a function has successfully resolved a value at least once (i.e., did not reject). Requires a spy function to be passed to `expect`.
1033+
1034+
If the function returned a promise, but it was not resolved yet, this will fail.
1035+
1036+
```ts twoslash
1037+
// @filename: db/apples.js
1038+
/** @type {any} */
1039+
const db = {}
1040+
export default db
1041+
// @filename: test.ts
1042+
// ---cut---
1043+
import { expect, test, vi } from 'vitest'
1044+
import db from './db/apples.js'
1045+
1046+
async function getApplesPrice(amount: number) {
1047+
return amount * await db.get('price')
1048+
}
1049+
1050+
test('spy function resolved a value', async () => {
1051+
const getPriceSpy = vi.fn(getApplesPrice)
1052+
1053+
const price = await getPriceSpy(10)
1054+
1055+
expect(price).toBe(100)
1056+
expect(getPriceSpy).toHaveResolved()
1057+
})
1058+
```
1059+
1060+
## toHaveResolvedTimes
1061+
1062+
- **Type**: `(amount: number) => Awaitable<void>`
1063+
1064+
This assertion checks if a function has successfully resolved a value an exact amount of times (i.e., did not reject). Requires a spy function to be passed to `expect`.
1065+
1066+
This will only count resolved promises. If the function returned a promise, but it was not resolved yet, it will not be counted.
1067+
1068+
```ts twoslash
1069+
import { expect, test, vi } from 'vitest'
1070+
1071+
test('spy function resolved a value two times', async () => {
1072+
const sell = vi.fn((product: string) => Promise.resolve({ product }))
1073+
1074+
await sell('apples')
1075+
await sell('bananas')
1076+
1077+
expect(sell).toHaveResolvedTimes(2)
1078+
})
1079+
```
1080+
1081+
## toHaveResolvedWith
1082+
1083+
- **Type**: `(returnValue: any) => Awaitable<void>`
1084+
1085+
You can call this assertion to check if a function has successfully resolved a certain value at least once. Requires a spy function to be passed to `expect`.
1086+
1087+
If the function returned a promise, but it was not resolved yet, this will fail.
1088+
1089+
```ts twoslash
1090+
import { expect, test, vi } from 'vitest'
1091+
1092+
test('spy function resolved a product', async () => {
1093+
const sell = vi.fn((product: string) => Promise.resolve({ product }))
1094+
1095+
await sell('apples')
1096+
1097+
expect(sell).toHaveResolvedWith({ product: 'apples' })
1098+
})
1099+
```
1100+
1101+
## toHaveLastResolvedWith
1102+
1103+
- **Type**: `(returnValue: any) => Awaitable<void>`
1104+
1105+
You can call this assertion to check if a function has successfully resolved a certain value when it was last invoked. Requires a spy function to be passed to `expect`.
1106+
1107+
If the function returned a promise, but it was not resolved yet, this will fail.
1108+
1109+
```ts twoslash
1110+
import { expect, test, vi } from 'vitest'
1111+
1112+
test('spy function resolves bananas on a last call', async () => {
1113+
const sell = vi.fn((product: string) => Promise.resolve({ product }))
1114+
1115+
await sell('apples')
1116+
await sell('bananas')
1117+
1118+
expect(sell).toHaveLastResolvedWith({ product: 'bananas' })
1119+
})
1120+
```
1121+
1122+
## toHaveNthResolvedWith
1123+
1124+
- **Type**: `(time: number, returnValue: any) => Awaitable<void>`
1125+
1126+
You can call this assertion to check if a function has successfully resolved a certain value on a specific invokation. Requires a spy function to be passed to `expect`.
1127+
1128+
If the function returned a promise, but it was not resolved yet, this will fail.
1129+
1130+
```ts twoslash
1131+
import { expect, test, vi } from 'vitest'
1132+
1133+
test('spy function returns bananas on second call', async () => {
1134+
const sell = vi.fn((product: string) => Promise.resolve({ product }))
1135+
1136+
await sell('apples')
1137+
await sell('bananas')
1138+
1139+
expect(sell).toHaveNthResolvedWith(2, { product: 'bananas' })
1140+
})
1141+
```
1142+
10281143
## toSatisfy
10291144

10301145
- **Type:** `(predicate: (value: any) => boolean) => Awaitable<void>`

docs/api/mock.md

+24-1
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ This is an array containing all values that were `returned` from the function. O
304304
- `'return'` - function returned without throwing.
305305
- `'throw'` - function threw a value.
306306

307-
The `value` property contains the returned value or thrown error. If the function returned a promise, the `value` will be the _resolved_ value, not the actual `Promise`, unless it was never resolved.
307+
The `value` property contains the returned value or thrown error. If the function returned a `Promise`, then `result` will always be `'return'` even if the promise was rejected.
308308

309309
```js
310310
const fn = vi.fn()
@@ -332,6 +332,29 @@ fn.mock.results === [
332332
]
333333
```
334334

335+
## mock.settledResults
336+
337+
An array containing all values that were `resolved` or `rejected` from the function.
338+
339+
This array will be empty if the function was never resolved or rejected.
340+
341+
```js
342+
const fn = vi.fn().mockResolvedValueOnce('result')
343+
344+
const result = fn()
345+
346+
fn.mock.settledResults === []
347+
348+
await result
349+
350+
fn.mock.settledResults === [
351+
{
352+
type: 'fulfilled',
353+
value: 'result',
354+
},
355+
]
356+
```
357+
335358
## mock.invocationCallOrder
336359

337360
The order of mock's execution. This returns an array of numbers that are shared between all defined mocks.

docs/guide/cli-table.md

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
| `--browser.provider <name>` | Provider used to run browser tests. Some browsers are only available for specific providers. Can be "webdriverio", "playwright", or the path to a custom provider. Visit [`browser.provider`](https://vitest.dev/config/#browser-provider) for more information (default: `"webdriverio"`) |
5757
| `--browser.providerOptions <options>` | Options that are passed down to a browser provider. Visit [`browser.providerOptions`](https://vitest.dev/config/#browser-provideroptions) for more information |
5858
| `--browser.isolate` | Run every browser test file in isolation. To disable isolation, use `--browser.isolate=false` (default: `true`) |
59+
| `--browser.ui` | Show Vitest UI when running tests (default: `!process.env.CI`) |
5960
| `--pool <pool>` | Specify pool, if not running in the browser (default: `threads`) |
6061
| `--poolOptions.threads.isolate` | Isolate tests in threads pool (default: `true`) |
6162
| `--poolOptions.threads.singleThread` | Run tests inside a single thread (default: `false`) |

0 commit comments

Comments
 (0)