Skip to content

Commit cad51f8

Browse files
committed
Add documentation for ignoreExtraArgs and .thenCallback()
1 parent 3077558 commit cad51f8

File tree

1 file changed

+94
-3
lines changed

1 file changed

+94
-3
lines changed

README.md

Lines changed: 94 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Wrap your `vi.fn()` mock - or a function imported from a `vi.mock`'d module - in
3737
- [`.thenThrow()`][then-throw] - Throw an error
3838
- [`.thenReject()`][then-reject] - Reject a `Promise`
3939
- [`.thenDo()`][then-do] - Trigger a function
40+
- [`.thenCallback()`][then-callback] - Invoke a callback argument
4041

4142
If the stub is called with arguments that match `calledWith`, the configured behavior will occur. If the arguments do not match, the stub will no-op and return `undefined`.
4243

@@ -76,6 +77,7 @@ You should call `vi.resetAllMocks()` in your suite's `afterEach` hook to remove
7677
[then-throw]: #thenthrowerror-unknown---mocktfunc
7778
[then-reject]: #thenrejecterror-unknown---mocktfunc
7879
[then-do]: #thendocallback-args-targs--treturn---mocktfunc
80+
[then-callback]: #thencallbackargs-unknown---mocktfunc
7981

8082
### Why not vanilla Vitest mocks?
8183

@@ -205,9 +207,10 @@ expect(mock()).toBe(undefined)
205207
import type { WhenOptions } from 'vitest-when'
206208
```
207209

208-
| option | default | type | description |
209-
| ------- | ------- | ------- | -------------------------------------------------- |
210-
| `times` | N/A | integer | Only trigger configured behavior a number of times |
210+
| option | default | type | description |
211+
| ----------------- | ------- | ------- | -------------------------------------------------- |
212+
| `times` | N/A | integer | Only trigger configured behavior a number of times |
213+
| `ignoreExtraArgs` | `false` | boolean | Match calls even when extra arguments are provided |
211214

212215
### `.calledWith(...args: Parameters<TFunc>): Stub<TFunc>`
213216

@@ -454,6 +457,94 @@ expect(mock('hello')).toEqual('world')
454457
expect(mock('hello')).toEqual('solar system')
455458
```
456459

460+
### `.thenCallback(...args: unknown[]) -> Mock<TFunc>`
461+
462+
When the stubbing is satisfied, invoke a callback function passed as an argument with the specified `args`. Use with [`expect.callback()`][expect-callback] to match callback arguments.
463+
464+
```ts
465+
const mock = when(vi.fn())
466+
.calledWith('data', expect.callback())
467+
.thenCallback('result')
468+
469+
mock('data', (value) => {
470+
console.log(value) // 'result'
471+
})
472+
```
473+
474+
If you don't specify `expect.callback()` in `calledWith`, an implied callback matcher is added as the last argument:
475+
476+
```ts
477+
const mock = when(vi.fn())
478+
.calledWith('data')
479+
.thenCallback('result')
480+
481+
mock('data', (value) => {
482+
console.log(value) // 'result'
483+
})
484+
```
485+
486+
Callbacks are invoked asynchronously on the next tick. Use [`nextTick()`][next-tick] to wait for callback execution:
487+
488+
```ts
489+
import { when, nextTick } from 'vitest-when'
490+
491+
const callback = vi.fn()
492+
const mock = when(vi.fn()).calledWith('hello').thenCallback('world')
493+
494+
mock('hello', callback)
495+
496+
await nextTick()
497+
expect(callback).toHaveBeenCalledWith('world')
498+
```
499+
500+
You can specify callback arguments directly in `expect.callback()` instead of `thenCallback()`:
501+
502+
```ts
503+
const mock = when(vi.fn())
504+
.calledWith(expect.callback('first'), expect.callback('second'))
505+
.thenReturn('done')
506+
507+
const cb1 = vi.fn()
508+
const cb2 = vi.fn()
509+
510+
mock(cb1, cb2)
511+
512+
await nextTick()
513+
expect(cb1).toHaveBeenCalledWith('first')
514+
expect(cb2).toHaveBeenCalledWith('second')
515+
```
516+
517+
[expect-callback]: #expectcallbackargs-unknown
518+
[next-tick]: #nexttick
519+
520+
### `expectCallback(...args: unknown[])`
521+
522+
This is the same as `expect.callback()`, but exported as `expectCallback` for use when the your tests use the context's `expect` function (e.g. `it('test', ({ expect }) => { ... }))`).
523+
524+
```ts
525+
import { when, expectCallback } from 'vitest-when'
526+
527+
when(mock).calledWith(expectCallback('arg')).thenReturn('result')
528+
// or
529+
when(mock).calledWith(expect.callback('arg')).thenReturn('result')
530+
```
531+
532+
### `nextTick()`
533+
534+
Returns a `Promise` that resolves on the next tick. Required when testing callbacks with `thenCallback()` since callbacks are invoked asynchronously.
535+
536+
```ts
537+
import { when, nextTick } from 'vitest-when'
538+
539+
const callback = vi.fn()
540+
when(mock).calledWith('test').thenCallback('value')
541+
542+
mock('test', callback)
543+
544+
await nextTick()
545+
expect(callback).toHaveBeenCalledWith('value')
546+
```
547+
457548
### `debug(mock: TFunc, options?: DebugOptions): DebugResult`
458549

459550
Logs and returns information about a mock's stubbing and usage. Useful if a test with mocks is failing and you can't figure out why.

0 commit comments

Comments
 (0)