vitest
2025.04.17
vitest
#test#javascript
use client /components/post/reExport ,
date: ,
tags: [ javascript https://antonarbus.com/imgs/xxx.png ,
body: (
<>
<H>Vitest</H>
<ul>
<li>
<Lnk path= >https://vitest.dev/</Lnk>
</li>
<li>
<Code>npm i -D vitest</Code>
</li>
<Code block json>{ : {
}
}
import { expect, test } from
import { sum } from
test( , () => {
expect(sum(1, 2)).toBe(3)
})
import { describe, it } from
// The two tests marked with concurrent will be started in parallel
describe( , () => {
it( , async () => { /* ... */ })
it.concurrent( , async ({ expect }) => { /* ... */ })
it.concurrent( , async ({ expect }) => { /* ... */ })
})
import { describe, it } from
// All tests within this suite will be started in parallel
describe.concurrent( , () => {
it( , async ({ expect }) => { /* ... */ })
it( , async ({ expect }) => { /* ... */ })
it.concurrent( , async ({ expect }) => { /* ... */ })
})
// the implementation
export function add(...args: number[]): number {
return args.reduce((a, b) => a + b, 0)
}
// in-source test suites
if (import.meta.vitest) {
const { it, expect } = import.meta.vitest
it( , () => {
expect(add()).toBe(0)
expect(add(1)).toBe(1)
expect(add(1, 2, 3)).toBe(6)
})
}
import { assertType, expectTypeOf, test } from
import { mount } from
test( , () => {
expectTypeOf(mount).toBeFunction()
expectTypeOf(mount).parameter(0).toMatchTypeOf<{ name: string }>()
// @ts-expect-error name is a string
assertType(mount({ name: 42 }))
})
import { expect, test } from
test( , () => {
expect(Math.sqrt(4)).toBe(2)
})
it( , () => {
expect(Math.sqrt(4)).toBe(2)
})
import { assert, test } from
test.skip( , () => {
// Test skipped, no error
assert.equal(Math.sqrt(4), 3)
})
import { assert, test } from
const isDev = process.env.NODE_ENV ===
test.skipIf(isDev)( , () => {
// this test only runs in production
})
import { assert, test } from
const isDev = process.env.NODE_ENV ===
test.runIf(isDev)( , () => {
// this test only runs in development
})
import { assert, test } from
test.only( , () => {
// Only this test (and others marked with only) are run
assert.equal(Math.sqrt(4), 2)
})
import { describe, test } from
// The two tests marked with concurrent will be run in parallel
describe( , () => {
test( , async () => { /* ... */ })
test.concurrent( , async () => { /* ... */ })
test.concurrent( , async () => { /* ... */ })
})
import { describe, test } from
// with config option { sequence: { concurrent: true } }
test( , async () => { /* ... */ })
test( , async () => { /* ... */ })
test.sequential( , async () => { /* ... */ })
test.sequential( , async () => { /* ... */ })
// within concurrent suite
describe.concurrent( , () => {
test( , async () => { /* ... */ })
test( , async () => { /* ... */ })
test.sequential( , async () => { /* ... */ })
test.sequential( , async () => { /* ... */ })
})
test.todo( }</Code>
<Hs>fails</Hs>
<p>Indicate that an assertion will fail explicitly</p>
<Code block jsx>{
function myAsyncFunc() {
return new Promise(resolve => resolve(1))
}
test.fails( , async () => {
await expect(myAsyncFunc()).rejects.toBe(1)
})
}
<Code>describe</Code> blocks can be nested to create a hierarchy of tests
</li>
</ul>
<Code block jsx>{
const person = {
isActive: true,
age: 32,
}
describe( , () => {
test( , () => {
expect(person).toBeDefined()
})
test( , () => {
expect(person.isActive).toBeTruthy()
})
test( , () => {
expect(person.age).toBeLessThanOrEqual(32)
})
})
import { beforeEach } from
beforeEach(async () => {
// Clear mocks and add some testing data after before each test run
await stopMocking()
await addUser({ name: })
})
// clean up function, called once after each test run
return async () => {
await resetSomething()
}
import { afterEach } from
afterEach(async () => {
await clearTestingData() // clear testing data after each test run
})
import { beforeAll } from
beforeAll(async () => {
// called once before all tests run
await startMocking()
// clean up function, called once after all tests run
return async () => {
await stopMocking()
}
})
import { afterAll } from
afterAll(async () => {
await stopMocking() // this method is called after all tests run
})
import { onTestFinished, test } from
test( , () => {
const db = connectDb()
onTestFinished(() => db.close())
db.query( )
})
import { test } from
test.concurrent( , ({ onTestFinished }) => {
const db = connectDb()
onTestFinished(() => db.close())
db.query( )
})
// this can be in a separate file
function getTestDb() {
const db = connectMockedDb()
onTestFinished(() => db.close())
return db
}
test( , async () => {
const db = getTestDb()
expect(
await db.query( ).perform()
).toEqual([])
})
test( , async () => {
const db = getTestDb()
expect(
await db.query( ).perform()
).toEqual([])
})
import { onTestFailed, test } from
test( , () => {
const db = connectDb()
onTestFailed((e) => {
console.log(e.result.errors)
})
db.query( )
})
import { expect, vi, it } from
it( , () => {
const fn = vi.fn()
fn( , 1)
expect(fn).toHaveBeenCalled()
expect(fn).toHaveBeenCalledWith( , 1)
// same as fn.mockReturnValue(arg)
// same as vi.fn(() => arg)
fn.mockImplementation((arg) => arg)
const res = fn( , 2)
expect(res).toBe( )
})
</code>
</li>
<li>
Then spy on specific function{ }
<code>{ myFunction }</code>
</li>
</ul>
<Code block jsx>{ original result }</Code>
<Code block jsx>{
export function run() {
return myFunction()
}
// 📁 main.test.ts
import { describe, it, expect, vi } from
import * as utilsModule from
import { run } from
vi.spyOn(utilsModule, ).mockImplementation(() => )
describe( , () => {
it( , () => {
expect(run()).toBe( )
})
})
// 📁 main.test.ts
// ✅ Auto-mock the entire module
vi.mock( )
import * as utilsModule from
import { run } from
describe( , () => {
it( , () => {
utilsModule.myFunction.mockImplementation(() => )
expect(run()).toBe( )
expect(utilsModule.myFunction).toHaveBeenCalled()
})
it( , () => {
utilsModule.myFunction.mockImplementation(() => )
expect(run()).toBe( )
expect(utilsModule.myFunction).toHaveBeenCalled()
})
})
import { describe, it, expect, vi } from
import axios from
vi.mock( ) // all methods become mocked with vi.fn()
it( , async () => {
axios.get.mockResolvedValue({ data: })
const response = await axios.get( )
expect(response.data).toBe( )
expect(axios.get).toHaveBeenCalledWith( )
})
import { describe, it, expect, vi } from
import axios from
vi.mock( ) // all methods become mocked with vi.fn()
it( , async () => {
vi.spyOn(axios, ).mockResolvedValue({ data: })
const response = await axios.get( )
expect(response.data).toBe( )
expect(axios.get).toHaveBeenCalledWith( )
})
import { describe, it, expect, vi } from
import axios from
// Dynamically mock axios
vi.mock(import( ), async (importOriginal) => {
const axios = await importOriginal()
return {
...axios, // Spread the original axios module
get: vi.fn(() => Promise.resolve({ data: })) // Mock only the get method
}
})
describe( , () => {
it( , async () => {
const response = await axios.get( )
expect(response.data).toBe( )
expect(axios.get).toHaveBeenCalledWith( )
// other axios methods (like post, delete, etc.) remain real
})
})