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