Skip to content

Commit f4a06fc

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

File tree

1 file changed

+92
-3
lines changed

1 file changed

+92
-3
lines changed

README.md

Lines changed: 92 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,92 @@ 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()).calledWith('data').thenCallback('result')
478+
479+
mock('data', (value) => {
480+
console.log(value) // 'result'
481+
})
482+
```
483+
484+
Callbacks are invoked asynchronously on the next tick. Use [`nextTick()`][next-tick] to wait for callback execution:
485+
486+
```ts
487+
import { when, nextTick } from 'vitest-when'
488+
489+
const callback = vi.fn()
490+
const mock = when(vi.fn()).calledWith('hello').thenCallback('world')
491+
492+
mock('hello', callback)
493+
494+
await nextTick()
495+
expect(callback).toHaveBeenCalledWith('world')
496+
```
497+
498+
You can specify callback arguments directly in `expect.callback()` instead of `thenCallback()`:
499+
500+
```ts
501+
const mock = when(vi.fn())
502+
.calledWith(expect.callback('first'), expect.callback('second'))
503+
.thenReturn('done')
504+
505+
const cb1 = vi.fn()
506+
const cb2 = vi.fn()
507+
508+
mock(cb1, cb2)
509+
510+
await nextTick()
511+
expect(cb1).toHaveBeenCalledWith('first')
512+
expect(cb2).toHaveBeenCalledWith('second')
513+
```
514+
515+
[expect-callback]: #expectcallbackargs-unknown
516+
[next-tick]: #nexttick
517+
518+
### `expectCallback(...args: unknown[])`
519+
520+
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 }) => { ... }))`).
521+
522+
```ts
523+
import { when, expectCallback } from 'vitest-when'
524+
525+
when(mock).calledWith(expectCallback('arg')).thenReturn('result')
526+
// or
527+
when(mock).calledWith(expect.callback('arg')).thenReturn('result')
528+
```
529+
530+
### `nextTick()`
531+
532+
Returns a `Promise` that resolves on the next tick. Required when testing callbacks with `thenCallback()` since callbacks are invoked asynchronously.
533+
534+
```ts
535+
import { when, nextTick } from 'vitest-when'
536+
537+
const callback = vi.fn()
538+
when(mock).calledWith('test').thenCallback('value')
539+
540+
mock('test', callback)
541+
542+
await nextTick()
543+
expect(callback).toHaveBeenCalledWith('value')
544+
```
545+
457546
### `debug(mock: TFunc, options?: DebugOptions): DebugResult`
458547

459548
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)