Skip to content

Commit

Permalink
docs: add mocking cheat sheet (#1536)
Browse files Browse the repository at this point in the history
* docs: add mocking cheat sheet

* docs: fix modules mocking example
  • Loading branch information
sheremet-va committed Jun 24, 2022
1 parent 34b06db commit adf82b3
Showing 1 changed file with 150 additions and 9 deletions.
159 changes: 150 additions & 9 deletions docs/guide/mocking.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,12 +164,14 @@ The following principles apply
### Example

```js
import { afterEach, beforeEach, describe, it, vi } from 'vitest'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { Client } from 'pg'
import { failure, success } from './handlers'

// handlers
export function success(data) {}
export function failure(data) {}

// get todos
export const getTodos = async (event, context) => {
const client = new Client({
Expand Down Expand Up @@ -199,16 +201,15 @@ export const getTodos = async (event, context) => {
}

vi.mock('pg', () => {
return {
Client: vi.fn(() => ({
connect: vi.fn(),
query: vi.fn(),
end: vi.fn(),
})),
}
const Client = vi.fn()
Client.prototype.connect = vi.fn()
Client.prototype.query = vi.fn()
Client.prototype.end = vi.fn()

return { Client }
})

vi.mock('./handler.js', () => {
vi.mock('./handlers', () => {
return {
success: vi.fn(),
failure: vi.fn(),
Expand Down Expand Up @@ -362,3 +363,143 @@ describe('delayed execution', () => {
})
})
```

## Cheat Sheet

:::info
`vi` in the examples below is imported directly from `vitest`. You can also use it globally, if you set `globals` to `true` in your [config](/config/).
:::

I want to…

- Spy on a `method`

```ts
const instance = new SomeClass()
vi.spyOn(instance, 'method')
```

- Spy on module export function
```ts
import * as exports from 'some-path'
vi.spyOn(exports, 'function')
```

- Spy on module export setter/getter
```ts
import * as exports from 'some-path'
vi.spyOn(exports, 'getter', 'get')
vi.spyOn(exports, 'setter', 'set')
```

- Mock a module export function

Example with `vi.mock`:
```ts
import { method } from 'some-path'
vi.mock('some-path', () => ({
method: vi.fn()
}))
```

Example with `vi.spyOn`:
```ts
import * as exports from 'some-path'
vi.spyOn(exports, 'method').mockImplementation(() => {})
```

- Mock a module export class implementation

Example with `vi.mock` and prototype:
```ts
import { SomeClass } from 'some-path'
vi.mock('some-path', () => {
const SomeClass = vi.fn()
SomeClass.prototype.someMethod = vi.fn()
return { SomeClass }
})
// SomeClass.mock.instances will have SomeClass
```

Example with `vi.mock` and return value:
```ts
import { SomeClass } from 'some-path'
vi.mock('some-path', () => {
const SomeClass = vi.fn(() => ({
someMethod: vi.fn()
}))
return { SomeClass }
})
// SomeClass.mock.returns will have returned object
```

Example with `vi.spyOn`:

```ts
import * as exports from 'some-path'
vi.spyOn(exports, 'SomeClass').mockImplementation(() => {
// whatever suites you from first two examples
})
```

- Spy on an object returned from a function

Example using cache:

```ts
// useObject.js
import { useObject } from 'some-path'
const obj = useObject()
obj.method()
```

```ts
// useObject.test.js
import { useObject } from 'some-path'
vi.mock('some-path', () => {
let _cache
const useObject = () => {
if (!_cache) {
_cache = {
method: vi.fn(),
}
}
return _cache
}
return { useObject }
})

const obj = useObject()
expect(obj.method).toHaveBeenCalled()
```

- Mock part of a module

```ts
import { mocked, original } from 'some-path'
vi.mock('some-path', async () => {
const mod = await vi.importActual<typeof import('some-path')>('some-path')
return {
...mod,
mocked: vi.fn()
}
})
original() // has original behaviour
mocked() // is a spy function
```

- Mock current date

```ts
const mockDate = new Date(2022, 0, 1)
vi.setSystemTime(mockDate)
const now = new Date()
expect(now.valueOf()).toBe(mockDate.valueOf())
```

- Mock global variable

```ts
vi.stubGlobal('__VERSION__', '1.0.0')
expect(__VERSION__).toBe('1.0.0')
```

0 comments on commit adf82b3

Please sign in to comment.