Vi
Vitestは、そのvi
ヘルパーを通じて支援するユーティリティ関数を提供します。グローバルにアクセスできます(globals設定が有効になっている場合)、またはvitest
から直接インポートできます。
import { vi } from 'vitest'
モックモジュール
このセクションでは、モジュールのモックを行う際に使用できるAPIについて説明します。Vitestはrequire()
を使用してインポートされたモジュールのモックをサポートしていないことに注意してください。
vi.mock
- 型:
(path: string, factory?: (importOriginal: () => unknown) => unknown) => void
指定されたpath
からのすべてのインポートされたモジュールを別のモジュールで置き換えます。パス内では設定されたViteエイリアスを使用できます。vi.mock
への呼び出しはホイスティングされるため、呼び出す場所を気にする必要はありません。常にすべてのインポートの前に実行されます。そのスコープ外の変数を参照する必要がある場合は、vi.hoisted
内で定義し、vi.mock
内で参照できます。
警告
vi.mock
は、import
キーワードでインポートされたモジュールに対してのみ機能します。require
では機能しません。
vi.mock
をホイスティングするために、Vitestは静的にファイルを解析します。これは、vitest
パッケージから直接インポートされていない(たとえば、一部のユーティリティファイルから)vi
は使用できないことを示しています。vitest
からインポートされたvi
でvi.mock
を使用するか、globals
設定オプションを有効にしてください。
Vitestは、セットアップファイル内でインポートされたモジュールをモックしません。テストファイルが実行されるまでにキャッシュされるためです。テストファイルを実行する前にすべてのモジュールキャッシュをクリアするには、vi.resetModules()
をvi.hoisted
内で呼び出すことができます。
factory
が定義されている場合、すべてのインポートはその結果を返します。vi.unmock
またはvi.doUnmock
が呼び出されるまで、Vitestはfactoryを1回だけ呼び出し、後続のすべてのインポートの結果をキャッシュします。
jest
とは異なり、factoryは非同期にすることができます。vi.importActual
または、最初の引数として渡されたfactoryを持つヘルパーを使用し、内部で元のモジュールを取得できます。
// when using JavaScript
.('./path/to/module.js', async () => {
const = await ()
return {
...,
// replace some exports
: .(),
}
})
// when using TypeScript
vi.mock('./path/to/module.js', async (importOriginal) => {
const mod = await importOriginal<typeof import('./path/to/module.js')>()
return {
...mod,
// replace some exports
namedExport: vi.fn(),
}
})
警告
vi.mock
はホイスティングされます(つまり、ファイルの先頭に移動されます)。つまり、どこ(beforeEach
内やtest
内など)に記述しても、実際にはそれよりも前に呼び出されるということです。
これはまた、factoryの外側で定義されている変数をfactory内で使用できないことを意味します。
factory内で変数を使用する必要がある場合は、vi.doMock
を試してください。同じように機能しますが、ホイスティングされません。後続のインポートのみをモックすることに注意してください。
vi.mock
の前に宣言されている場合、vi.hoisted
メソッドによって定義された変数を参照することもできます。
import { namedExport } from './path/to/module.js'
const mocks = vi.hoisted(() => {
return {
namedExport: vi.fn(),
}
})
vi.mock('./path/to/module.js', () => {
return {
namedExport: mocks.namedExport,
}
})
vi.mocked(namedExport).mockReturnValue(100)
expect(namedExport()).toBe(100)
expect(namedExport).toBe(mocks.namedExport)
警告
デフォルトエクスポートを持つモジュールをモックする場合は、返されたfactory関数オブジェクト内にdefault
キーを指定する必要があります。これはESモジュール固有の注意点です。そのため、jest
はCommonJSモジュールを使用するため、jest
のドキュメントとは異なる場合があります。例:
vi.mock('./path/to/module.js', () => {
return {
default: { myDefaultKey: vi.fn() },
namedExport: vi.fn(),
// etc...
}
})
モックしているファイルと並んで__mocks__
フォルダがあり、factoryが提供されていない場合、Vitestは__mocks__
サブフォルダに同じ名前のファイルを探し、それを実際のモジュールとして使用しようとします。依存関係をモックしている場合、Vitestはプロジェクトのルート(デフォルトはprocess.cwd()
)に__mocks__
フォルダを探します。依存関係の場所をdeps.moduleDirectories設定オプションを使用してVitestに指示できます。
たとえば、次のファイル構造があるとします。
- __mocks__
- axios.js
- src
__mocks__
- increment.js
- increment.js
- tests
- increment.test.js
factoryが提供されずにテストファイルでvi.mock
を呼び出すと、モジュールとして使用する__mocks__
フォルダ内のファイルが検出されます。
// increment.test.js
import { vi } from 'vitest'
// axios is a default export from `__mocks__/axios.js`
import axios from 'axios'
// increment is a named export from `src/__mocks__/increment.js`
import { increment } from '../increment.js'
vi.mock('axios')
vi.mock('../increment.js')
axios.get(`/apples/${increment(1)}`)
警告
vi.mock
を呼び出さない場合、モジュールは自動的にモックされないことに注意してください。Jestの自動モック動作を複製するには、setupFiles
内で必要な各モジュールに対してvi.mock
を呼び出すことができます。
__mocks__
フォルダまたは提供されたfactoryがない場合、Vitestは元のモジュールをインポートし、そのすべてのエクスポートを自動的にモックします。適用されるルールについては、アルゴリズムを参照してください。
vi.doMock
- 型:
(path: string, factory?: (importOriginal: () => unknown) => unknown) => void
vi.mock
と同じですが、ファイルの先頭にホイスティングされないため、グローバルファイルスコープの変数を参照できます。モジュールの次の動的インポートがモックされます。
警告
これにより、これの前にインポートされたモジュールはモックされません。ESMのすべての静的インポートは常にホイスティングされるため、これを静的インポートの前に配置しても、インポートの前に呼び出されるようにはなりません。
vi.doMock('./increment.js') // this will be called _after_ the import statement
import { increment } from './increment.js'
// ./increment.js
export function increment(number) {
return number + 1
}
import { beforeEach, test } from 'vitest'
import { increment } from './increment.js'
// the module is not mocked, because vi.doMock is not called yet
increment(1) === 2
let mockedIncrement = 100
beforeEach(() => {
// you can access variables inside a factory
vi.doMock('./increment.js', () => ({ increment: () => ++mockedIncrement }))
})
test('importing the next module imports mocked one', async () => {
// original import WAS NOT MOCKED, because vi.doMock is evaluated AFTER imports
expect(increment(1)).toBe(2)
const { increment: mockedIncrement } = await import('./increment.js')
// new dynamic import returns mocked module
expect(mockedIncrement(1)).toBe(101)
expect(mockedIncrement(1)).toBe(102)
expect(mockedIncrement(1)).toBe(103)
})
vi.mocked
- 型:
<T>(obj: T, deep?: boolean) => MaybeMockedDeep<T>
- 型:
<T>(obj: T, options?: { partial?: boolean; deep?: boolean }) => MaybePartiallyMockedDeep<T>
TypeScriptの型ヘルパー。渡されたオブジェクトをそのまま返します。
partial
がtrue
の場合、Partial<T>
を戻り値として期待します。デフォルトでは、TypeScriptは最上位レベルの値のみがモックされていると判断します。実際にはオブジェクト全体がモックされていることをTypeScriptに伝えるには、第2引数として{ deep: true }
を渡すことができます。
import example from './example.js'
vi.mock('./example.js')
test('1 + 1 equals 10', async () => {
vi.mocked(example.calc).mockReturnValue(10)
expect(example.calc(1, '+', 1)).toBe(10)
})
vi.importActual
- 型:
<T>(path: string) => Promise<T>
モックするかどうかすべてのチェックをバイパスして、モジュールをインポートします。モジュールを部分的にモックしたい場合に役立ちます。
vi.mock('./example.js', async () => {
const axios = await vi.importActual('./example.js')
return { ...axios, get: vi.fn() }
})
vi.importMock
- 型:
<T>(path: string) => Promise<MaybeMockedDeep<T>>
すべてのプロパティ(ネストされたプロパティを含む)がモックされたモジュールをインポートします。vi.mock
と同じルールに従います。適用されるルールについては、アルゴリズムを参照してください。
vi.unmock
- 型:
(path: string) => void
モックレジストリからモジュールを削除します。インポートへのすべての呼び出しは、以前モックされていた場合でも、元のモジュールを返します。この呼び出しはファイルの先頭にホイスティングされるため、たとえばsetupFiles
で定義されたモジュールのみがアンモックされます。
vi.doUnmock
- 型:
(path: string) => void
vi.unmock
と同じですが、ファイルの先頭にホイスティングされません。モジュールの次のインポートは、モックではなく元のモジュールをインポートします。これにより、以前にインポートされたモジュールはアンモックされません。
// ./increment.js
export function increment(number) {
return number + 1
}
import { increment } from './increment.js'
// increment is already mocked, because vi.mock is hoisted
increment(1) === 100
// this is hoisted, and factory is called before the import on line 1
vi.mock('./increment.js', () => ({ increment: () => 100 }))
// all calls are mocked, and `increment` always returns 100
increment(1) === 100
increment(30) === 100
// this is not hoisted, so other import will return unmocked module
vi.doUnmock('./increment.js')
// this STILL returns 100, because `vi.doUnmock` doesn't reevaluate a module
increment(1) === 100
increment(30) === 100
// the next import is unmocked, now `increment` is the original function that returns count + 1
const { increment: unmockedIncrement } = await import('./increment.js')
unmockedIncrement(1) === 2
unmockedIncrement(30) === 31
vi.resetModules
- 型:
() => Vitest
すべてのモジュールのキャッシュをクリアすることで、モジュールレジストリをリセットします。これにより、再インポート時にモジュールを再評価できます。トップレベルのインポートは再評価できません。テスト間のローカル状態の競合を分離する場合に役立つ場合があります。
import { vi } from 'vitest'
import { data } from './data.js' // Will not get reevaluated beforeEach test
beforeEach(() => {
vi.resetModules()
})
test('change state', async () => {
const mod = await import('./some/path.js') // Will get reevaluated
mod.changeLocalState('new value')
expect(mod.getLocalState()).toBe('new value')
})
test('module has old state', async () => {
const mod = await import('./some/path.js') // Will get reevaluated
expect(mod.getLocalState()).toBe('old value')
})
警告
モックレジストリはリセットしません。モックレジストリをクリアするには、vi.unmock
またはvi.doUnmock
を使用します。
vi.dynamicImportSettled
すべてのインポートの読み込みを待ちます。それ以外の方法では待てないモジュールのインポートを開始する同期呼び出しがある場合に役立ちます。
import { expect, test } from 'vitest'
// cannot track import because Promise is not returned
function renderComponent() {
import('./component.js').then(({ render }) => {
render()
})
}
test('operations are resolved', async () => {
renderComponent()
await vi.dynamicImportSettled()
expect(document.querySelector('.component')).not.toBeNull()
})
ヒント
動的インポート中に別の動的インポートが開始された場合、このメソッドはすべてが解決されるまで待ちます。
このメソッドは、インポートが解決された後の次のsetTimeout
ティックも待機するため、同期操作はすべて解決されるまでに完了している必要があります。
関数とオブジェクトのモック
このセクションでは、メソッドモックの使用方法と、環境変数およびグローバル変数の置き換えについて説明します。
vi.fn
- 型:
(fn?: Function) => Mock
関数に対するスパイを作成しますが、関数なしで開始することもできます。関数が呼び出されるたびに、その呼び出し引数、戻り値、インスタンスを格納します。また、メソッドを使用して動作を操作できます。関数が指定されていない場合、モックは呼び出されるとundefined
を返します。
const = .(() => 0)
()
().()
().(0)
.(5)
const = ()
().(5)
().(2, 5)
vi.isMockFunction
- 型:
(fn: Function) => boolean
指定されたパラメータがモック関数であるかどうかを確認します。TypeScriptを使用している場合、その型も絞り込まれます。
vi.clearAllMocks
すべてのスパイに対して.mockClear()
を呼び出します。これによりモック履歴がクリアされますが、実装はデフォルトのものにリセットされません。
vi.resetAllMocks
すべてのスパイに対して.mockReset()
を呼び出します。これによりモック履歴がクリアされ、実装が空の関数(undefined
を返す)にリセットされます。
vi.restoreAllMocks
すべてのスパイに対して.mockRestore()
を呼び出します。これによりモック履歴がクリアされ、実装が元の状態にリセットされます。
vi.spyOn
- 型:
<T, K extends keyof T>(object: T, method: K, accessType?: 'get' | 'set') => MockInstance
vi.fn()
に似て、オブジェクトのメソッドまたはゲッター/セッターに対するスパイを作成します。モック関数を返します。
let = 0
const = {
: () => 42,
}
const = .(, 'getApples').(() => )
= 1
(.()).(1)
().()
().(1)
ヒント
afterEach
内でvi.restoreAllMocks
を呼び出す(またはtest.restoreMocks
を有効にする)ことで、すべてのメソッドを元の状態に復元できます。これにより、元のオブジェクト記述子が復元されるため、メソッドの実装を変更できなくなります。
const cart = {
getApples: () => 42,
}
const spy = vi.spyOn(cart, 'getApples').mockReturnValue(10)
console.log(cart.getApples()) // 10
vi.restoreAllMocks()
console.log(cart.getApples()) // 42
spy.mockReturnValue(10)
console.log(cart.getApples()) // still 42!
vi.stubEnv 0.26.0+
- 型:
(name: string, value: string) => Vitest
process.env
とimport.meta.env
の環境変数の値を変更します。vi.unstubAllEnvs
を呼び出すことで、元の値に戻すことができます。
import { vi } from 'vitest'
// `process.env.NODE_ENV` and `import.meta.env.NODE_ENV`
// are "development" before calling "vi.stubEnv"
vi.stubEnv('NODE_ENV', 'production')
process.env.NODE_ENV === 'production'
import.meta.env.NODE_ENV === 'production'
// doesn't change other envs
import.meta.env.MODE === 'development'
ヒント
単純に値を代入して変更することもできますが、その場合はvi.unstubAllEnvs
を使用して以前の値を復元することはできません。
import.meta.env.MODE = 'test'
vi.unstubAllEnvs 0.26.0+
- 型:
() => Vitest
vi.stubEnv
で変更されたすべてのimport.meta.env
とprocess.env
の値を復元します。最初に呼び出された際に、Vitestは元の値を記憶し、unstubAllEnvs
が再び呼び出されるまで保存します。
import { vi } from 'vitest'
// `process.env.NODE_ENV` and `import.meta.env.NODE_ENV`
// are "development" before calling stubEnv
vi.stubEnv('NODE_ENV', 'production')
process.env.NODE_ENV === 'production'
import.meta.env.NODE_ENV === 'production'
vi.stubEnv('NODE_ENV', 'staging')
process.env.NODE_ENV === 'staging'
import.meta.env.NODE_ENV === 'staging'
vi.unstubAllEnvs()
// restores to the value that were stored before the first "stubEnv" call
process.env.NODE_ENV === 'development'
import.meta.env.NODE_ENV === 'development'
vi.stubGlobal
- 型:
(name: string | number | symbol, value: unknown) => Vitest
グローバル変数の値を変更します。vi.unstubAllGlobals
を呼び出すことで、元の値に戻すことができます。
import { } from 'vitest'
// `innerWidth` is "0" before calling stubGlobal
.('innerWidth', 100)
=== 100
. === 100
// if you are using jsdom or happy-dom
. === 100
ヒント
globalThis
またはwindow
(jsdom
またはhappy-dom
環境を使用している場合)に単純に値を代入して変更することもできますが、その場合はvi.unstubAllGlobals
を使用して元の値を復元することはできません。
globalThis.innerWidth = 100
// if you are using jsdom or happy-dom
window.innerWidth = 100
vi.unstubAllGlobals 0.26.0+
- 型:
() => Vitest
vi.stubGlobal
で変更されたすべてのグローバル値(globalThis
/global
、およびjsdom
またはhappy-dom
環境を使用している場合はwindow
/top
/self
/parent
)を復元します。最初に呼び出された際に、Vitestは元の値を記憶し、unstubAllGlobals
が再び呼び出されるまで保存します。
import { vi } from 'vitest'
const Mock = vi.fn()
// IntersectionObserver is "undefined" before calling "stubGlobal"
vi.stubGlobal('IntersectionObserver', Mock)
IntersectionObserver === Mock
global.IntersectionObserver === Mock
globalThis.IntersectionObserver === Mock
// if you are using jsdom or happy-dom
window.IntersectionObserver === Mock
vi.unstubAllGlobals()
globalThis.IntersectionObserver === undefined
'IntersectionObserver' in globalThis === false
// throws ReferenceError, because it's not defined
IntersectionObserver === undefined
疑似タイマー
このセクションでは、疑似タイマーの使用方法について説明します。
vi.advanceTimersByTime
- 型:
(ms: number) => Vitest
このメソッドは、指定されたミリ秒数が経過するか、キューが空になるまで(どちらか先に来るまで)、開始されたすべてのタイマーを呼び出します。
let = 0
(() => .(++), 50)
.(150)
// log: 1
// log: 2
// log: 3
vi.advanceTimersByTimeAsync
- 型:
(ms: number) => Promise<Vitest>
このメソッドは、指定されたミリ秒数が経過するか、キューが空になるまで(どちらか先に来るまで)、開始されたすべてのタイマーを呼び出します。非同期で設定されたタイマーも含まれます。
let = 0
(() => .().(() => .(++)), 50)
await .(150)
// log: 1
// log: 2
// log: 3
vi.advanceTimersToNextTimer
- 型:
() => Vitest
次に利用可能なタイマーを呼び出します。各タイマー呼び出し間のassertionに役立ちます。自身でタイマーを管理するために、チェーン呼び出しを行うことができます。
let = 0
(() => .(++), 50)
.() // log: 1
.() // log: 2
.() // log: 3
vi.advanceTimersToNextTimerAsync
- 型:
() => Promise<Vitest>
次に利用可能なタイマーを呼び出し、非同期で設定された場合は解決されるまで待機します。各タイマー呼び出し間のassertionに役立ちます。
let = 0
(() => .().(() => .(++)), 50)
await .() // log: 1
(.).(1)
await .() // log: 2
await .() // log: 3
vi.getTimerCount
- 型:
() => number
待機中のタイマーの数を取得します。
vi.clearAllTimers
実行される予定のすべてのタイマーを削除します。これらのタイマーは将来実行されることはありません。
vi.getMockedSystemTime
- 型:
() => Date | null
setSystemTime
を使用して設定された、モックされた現在の日時を返します。日時がモックされていない場合、このメソッドはnull
を返します。
vi.getRealSystemTime
- 型:
() => number
vi.useFakeTimers
を使用している場合、Date.now
の呼び出しはモックされます。ミリ秒単位の実時間を取得する必要がある場合は、この関数を使用できます。
vi.runAllTicks
- 型:
() => Vitest
process.nextTick
によってキューに入れられたすべてのmicrotaskを呼び出します。これにより、それ自体によってスケジュールされたすべてのmicrotaskも実行されます。
vi.runAllTimers
- 型:
() => Vitest
このメソッドは、タイマーキューが空になるまで、開始されたすべてのタイマーを呼び出します。つまり、runAllTimers
中に呼び出されたすべてのタイマーが発火します。無限のintervalがある場合、10000回の試行後にエラーをスローします(fakeTimers.loopLimit
で設定できます)。
let = 0
(() => .(++))
const = (() => {
.(++)
if ( === 3)
()
}, 50)
.()
// log: 1
// log: 2
// log: 3
vi.runAllTimersAsync
- 型:
() => Promise<Vitest>
このメソッドは、タイマーキューが空になるまで、開始されたすべてのタイマーを非同期的に呼び出します。つまり、runAllTimersAsync
中に呼び出されたすべてのタイマー(非同期タイマーを含む)が発火します。無限のintervalがある場合、10000回の試行後にエラーをスローします(fakeTimers.loopLimit
で設定できます)。
(async () => {
.(await .('result'))
}, 100)
await .()
// log: result
vi.runOnlyPendingTimers
- 型:
() => Vitest
このメソッドは、vi.useFakeTimers
呼び出し後に開始されたすべてのタイマーを呼び出します。その呼び出し中に開始されたタイマーは発火しません。
let = 0
(() => .(++), 50)
.()
// log: 1
vi.runOnlyPendingTimersAsync
- 型:
() => Promise<Vitest>
このメソッドは、vi.useFakeTimers
呼び出し後に開始されたすべてのタイマー(非同期タイマーを含む)を非同期的に呼び出します。その呼び出し中に開始されたタイマーは発火しません。
(() => {
.(1)
}, 100)
(() => {
.().(() => {
.(2)
(() => {
.(3)
}, 40)
})
}, 10)
await .()
// log: 2
// log: 3
// log: 3
// log: 1
vi.setSystemTime
- 型:
(date: string | number | Date) => void
疑似タイマーが有効になっている場合、このメソッドはユーザーがシステムクロックを変更したことをシミュレートします(hrtime
、performance.now
、new Date()
などの日付関連のAPIに影響します)。ただし、タイマーは発火しません。疑似タイマーが無効になっている場合、このメソッドはDate.*
呼び出しのみをモックします。
現在の日時に依存するものをテストする必要がある場合(たとえば、コード内のLuxon呼び出し)に役立ちます。
const = new (1998, 11, 19)
.()
.()
(.()).(.())
.()
vi.useFakeTimers
- 型:
(config?: FakeTimerInstallOpts) => Vitest
タイマーのモックを有効にするには、このメソッドを呼び出す必要があります。vi.useRealTimers()
が呼び出されるまで、すべてのタイマー呼び出し(setTimeout
、setInterval
、clearTimeout
、clearInterval
、setImmediate
、clearImmediate
、Date
など)をラップします。
--pool=forks
を使用してnode:child_process
内でVitestを実行している場合、nextTick
のモックはサポートされていません。NodeJSはnode:child_process
内で内部的にprocess.nextTick
を使用しており、モックされるとハングします。--pool=threads
を使用してVitestを実行している場合、nextTick
のモックはサポートされています。
実装は内部的に@sinonjs/fake-timers
に基づいています。
ヒント
バージョン0.35.0
以降、vi.useFakeTimers()
はprocess.nextTick
を自動的にモックしなくなりました。toFake
引数にオプションを指定することで、引き続きモックできます: vi.useFakeTimers({ toFake: ['nextTick'] })
。
vi.isFakeTimers 0.34.5+
- 型:
() => boolean
疑似タイマーが有効になっている場合はtrue
を返します。
vi.useRealTimers
- 型:
() => Vitest
タイマーが実行された後、このメソッドを呼び出して、モックされたタイマーを元のimplementationに戻すことができます。それ以前にスケジュールされたすべてのタイマーは破棄されます。
その他
Vitestが提供する便利なヘルパー関数のセットです。
vi.waitFor 0.34.5+
- 型:
<T>(callback: WaitForCallback<T>, options?: number | WaitForOptions) => Promise<T>
コールバックが正常に実行されるまで待ちます。コールバックがエラーをスローするか、拒否されたPromiseを返す場合、成功するかタイムアウトするまで待ち続けます。
これは、非同期アクションが完了するのを待つ必要がある場合(たとえば、サーバーを起動して起動するのを待つ必要がある場合)に非常に便利です。
import { expect, test, vi } from 'vitest'
import { createServer } from './server.js'
test('Server started successfully', async () => {
const server = createServer()
await vi.waitFor(
() => {
if (!server.isReady)
throw new Error('Server not started')
console.log('Server started')
},
{
timeout: 500, // default is 1000
interval: 20, // default is 50
}
)
expect(server.isReady).toBe(true)
})
非同期コールバックにも対応しています。
// @vitest-environment jsdom
import { expect, test, vi } from 'vitest'
import { getDOMElementAsync, populateDOMAsync } from './dom.js'
test('Element exists in a DOM', async () => {
// start populating DOM
populateDOMAsync()
const element = await vi.waitFor(async () => {
// try to get the element until it exists
const element = await getDOMElementAsync() as HTMLElement | null
expect(element).toBeTruthy()
expect(element.dataset.initialized).toBeTruthy()
return element
}, {
timeout: 500, // default is 1000
interval: 20, // default is 50
})
expect(element).toBeInstanceOf(HTMLElement)
})
vi.useFakeTimers
が使用されている場合、vi.waitFor
は各チェックコールバックで自動的にvi.advanceTimersByTime(interval)
を呼び出します。
vi.waitUntil 0.34.5+
- 型:
<T>(callback: WaitUntilCallback<T>, options?: number | WaitUntilOptions) => Promise<T>
これはvi.waitFor
に似ていますが、コールバックがエラーをスローすると、実行はすぐに中断され、エラーメッセージが表示されます。コールバックがfalsyな値を返す場合、truthyな値が返されるまで次のチェックが継続されます。これは、次のステップに進む前に何かが存在するのを待つ必要がある場合に便利です。
下の例を参照してください。vi.waitUntil
を使用してページに要素が表示されるのを待つことができ、その後、その要素に対して何かを実行できます。
import { , , } from 'vitest'
('Element render correctly', async () => {
const = await .(
() => .('.element'),
{
: 500, // default is 1000
: 20, // default is 50
}
)
// do something with the element
(.('.element-child')).()
})
vi.hoisted 0.31.0+
- 型:
<T>(factory: () => T) => T
ESモジュールのすべてのstaticなimport
文はファイルの先頭にhoistedされるため、importの前に定義されているコードは、実際にはimportが評価された後に実行されます。
ただし、モジュールをimportする前に、日付のモックなど、いくつかの副作用を呼び出すことが役立つ場合があります。
この制限を回避するために、staticなimportを次のようにdynamicなimportに書き換えることができます。
callFunctionWithSideEffect()
- import { value } from './some/module.js'
+ const { value } = await import('./some/module.js')
vitest
を実行する際、vi.hoisted
メソッドを使用することでこれを自動的に行うことができます。
- callFunctionWithSideEffect()
import { value } from './some/module.js'
+ vi.hoisted(() => callFunctionWithSideEffect())
このメソッドは、ファクトリから返された値を返します。ローカルで定義された変数に簡単にアクセスする必要がある場合、vi.mock
ファクトリでその値を使用できます。
import { expect, vi } from 'vitest'
import { originalMethod } from './path/to/module.js'
const { mockedMethod } = vi.hoisted(() => {
return { mockedMethod: vi.fn() }
})
vi.mock('./path/to/module.js', () => {
return { originalMethod: mockedMethod }
})
mockedMethod.mockReturnValue(100)
expect(originalMethod()).toBe(100)
このメソッドは、環境がトップレベルのawaitをサポートしていなくても、非同期的に呼び出すことができることに注意してください。
const promised = await vi.hoisted(async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/posts')
return response.json()
})
vi.setConfig
- 型:
RuntimeConfig
現在のテストファイルのconfigを更新します。このメソッドは、現在のテストファイルに影響を与えるconfigオプションのみをサポートします。
vi.setConfig({
allowOnly: true,
testTimeout: 10_000,
hookTimeout: 10_000,
clearMocks: true,
restoreMocks: true,
fakeTimers: {
now: new Date(2021, 11, 19),
// supports the whole object
},
maxConcurrency: 10,
sequence: {
hooks: 'stack'
// supports only "sequence.hooks"
}
})
vi.resetConfig
- 型:
RuntimeConfig
vi.setConfig
が以前に呼び出された場合、これによりconfigが元の状態にリセットされます。