跳到主要内容

Mocking

You can import { vi } from 'vitest' or access it globally (when global configuration is enabled)

Dates

Vitest uses @sinonjs/fake-timers package for manipulating timers, as well as system date

  • vi.useFakeTimers()
  • vi.setSystemTime(date)
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'

const businessHours = [9, 17]

const purchase = () => {
const currentHour = new Date().getHours()
const [open, close] = businessHours

if (currentHour > open && currentHour < close)
return { message: 'Success' }

return { message: 'Error' }
}

describe('purchasing flow', () => {
beforeEach(() => {
// tell vitest we use mocked time
vi.useFakeTimers()
})

afterEach(() => {
// restoring date after each test run
vi.useRealTimers()
})

it('allows purchases within business hours', () => {
// set hour within business hours
const date = new Date(2000, 1, 1, 13)
vi.setSystemTime(date)

// access Date.now() will result in the date set above
expect(purchase()).toEqual({ message: 'Success' })
})

it('disallows purchases outside of business hours', () => {
// set hour outside business hours
const date = new Date(2000, 1, 1, 19)
vi.setSystemTime(date)

// access Date.now() will result in the date set above
expect(purchase()).toEqual({ message: 'Error' })
})
})

Functions

However spies can only help you spy on functions, they are not able to alter the implementation of those functions. In the case where we do need to create a fake (or mocked) version of a function we can use vi.fn()

  • const spy = vi.spyOn(messages, 'getLatest')
  • spy.mockImplementationOnce
  • vi.restoreAllMocks()
  • const mock = vi.fn().mockImplementation(getLatest)
import { afterEach, describe, expect, it, vi } from 'vitest'

const getLatest = (index = messages.items.length - 1) => messages.items[index]

const messages = {
items: [
{ message: 'Simple test message', from: 'Testman' },
// ...
],
getLatest, // can also be a `getter or setter if supported`
}

describe('reading messages', () => {
afterEach(() => {
vi.restoreAllMocks()
})

it('should get the latest message with a spy', () => {
const spy = vi.spyOn(messages, 'getLatest')
expect(spy.getMockName()).toEqual('getLatest')

expect(messages.getLatest()).toEqual(
messages.items[messages.items.length - 1],
)

expect(spy).toHaveBeenCalledTimes(1)

spy.mockImplementationOnce(() => 'access-restricted')
expect(messages.getLatest()).toEqual('access-restricted')

expect(spy).toHaveBeenCalledTimes(2)
})

it('should get with a mock', () => {
const mock = vi.fn().mockImplementation(getLatest)

expect(mock()).toEqual(messages.items[messages.items.length - 1])
expect(mock).toHaveBeenCalledTimes(1)

mock.mockImplementationOnce(() => 'access-restricted')
expect(mock()).toEqual('access-restricted')

expect(mock).toHaveBeenCalledTimes(2)

expect(mock()).toEqual(messages.items[messages.items.length - 1])
expect(mock).toHaveBeenCalledTimes(3)
})
})

Timers

  • vi.useFakeTimers()
  • vi.restoreAllMocks()
  • vi.runAllTimers()
  • vi.advanceTimersByTime(2)
  • vi.advanceTimersToNextTimer()