Skip to content
Vitest 0
Main Navigation 가이드API구성고급
1.6.1
0.34.6

한국어

English
简体中文
繁體中文
Español
Français
Русский
Português – Brasil
Deutsch
日本語
Italiano
Polski
Türkçe
čeština
magyar

한국어

English
简体中文
繁體中文
Español
Français
Русский
Português – Brasil
Deutsch
日本語
Italiano
Polski
Türkçe
čeština
magyar

외관

Sidebar Navigation

가이드

Vitest를 선택하는 이유

시작하기

기능

워크스페이스

명령줄 인터페이스

테스트 필터링

커버리지

스냅샷

모의화

타입 테스트

Vitest UI

브라우저 모드 (실험적)

소스 내 테스트

테스트 컨텍스트

테스트 환경

Matcher 확장하기

IDE 통합

디버깅

다른 테스트 러너와의 비교

마이그레이션 가이드

일반적인 오류

API

테스트 API 참조

Mock 함수

Vi

expect

expectTypeOf

assertType

구성

Vitest 설정하기

이 페이지에서

Vi ​

Vitest는 vi 헬퍼를 통해 유틸리티 기능을 제공합니다. 전역적으로 접근하거나 (globals configuration이 활성화된 경우), vitest에서 가져올 수 있습니다.

js
import { vi } from 'vitest';

vi.advanceTimersByTime ​

  • 타입: (ms: number) => Vitest

    runAllTimers와 동일하게 작동하지만, 지정된 밀리초만큼 시간이 경과한 후 종료됩니다. 예를 들어, 다음 코드는 1, 2, 3을 기록하고 오류를 발생시키지 않습니다.

    ts
    let i = 0;
    setInterval(() => console.log(++i), 50);
    
    vi.advanceTimersByTime(150);

vi.advanceTimersByTimeAsync ​

  • 타입: (ms: number) => Promise<Vitest>

    runAllTimersAsync와 동일하게 작동하지만, 지정된 밀리초만큼 시간이 경과한 후 종료됩니다. 비동기적으로 설정된 타이머도 포함됩니다. 예를 들어, 다음 코드는 1, 2, 3을 기록하고 오류를 발생시키지 않습니다.

    ts
    let i = 0;
    setInterval(() => Promise.resolve().then(() => console.log(++i)), 50);
    
    await vi.advanceTimersByTimeAsync(150);

vi.advanceTimersToNextTimer ​

  • 타입: () => Vitest

    다음으로 실행될 타이머를 실행합니다. 각 타이머 실행 사이에 assertion을 수행하는 데 유용합니다. 메서드 체이닝을 통해 타이머를 직접 관리할 수 있습니다.

    ts
    let i = 0;
    setInterval(() => console.log(++i), 50);
    
    vi.advanceTimersToNextTimer() // log 1
      .advanceTimersToNextTimer() // log 2
      .advanceTimersToNextTimer(); // log 3

vi.advanceTimersToNextTimerAsync ​

  • 타입: () => Promise<Vitest>

    비동기적으로 설정된 타이머를 포함하여 다음으로 실행될 타이머를 실행합니다. 각 타이머 실행 사이에 assertion을 수행하는 데 유용합니다. 메서드 체이닝을 통해 타이머를 직접 관리할 수 있습니다.

    ts
    let i = 0;
    setInterval(() => Promise.resolve().then(() => console.log(++i)), 50);
    
    vi.advanceTimersToNextTimerAsync() // log 1
      .advanceTimersToNextTimerAsync() // log 2
      .advanceTimersToNextTimerAsync(); // log 3

vi.getTimerCount ​

  • 타입: () => number

    현재 대기 중인 타이머의 수를 반환합니다.

vi.clearAllMocks ​

모든 스파이(spy)에서 .mockClear()를 호출합니다. 이는 mock 히스토리를 초기화하지만, 구현은 기본값으로 재설정하지 않습니다.

vi.clearAllTimers ​

실행되도록 예약된 모든 타이머를 제거합니다. 제거된 타이머는 더 이상 실행되지 않습니다.

vi.dynamicImportSettled ​

모든 import가 완료될 때까지 기다립니다. 모듈을 동기적으로 import하는 호출이 있을 때, 다른 방법으로는 완료를 기다릴 수 없는 경우 유용합니다.

vi.fn ​

  • 타입: (fn?: Function) => Mock

    함수에 대한 스파이(spy) 함수를 생성합니다. 함수 없이 초기화할 수도 있습니다. 함수가 호출될 때마다 호출 인수, 반환 값 및 인스턴스를 저장합니다. 또한 메서드를 사용하여 동작을 조작할 수 있습니다. 함수가 제공되지 않으면 mock은 호출될 때 undefined를 반환합니다.

    ts
    const getApples = vi.fn(() => 0);
    
    getApples();
    
    expect(getApples).toHaveBeenCalled();
    expect(getApples).toHaveReturnedWith(0);
    
    getApples.mockReturnValueOnce(5);
    
    const res = getApples();
    expect(res).toBe(5);
    expect(getApples).toHaveNthReturnedWith(2, 5);

vi.getMockedSystemTime ​

  • 타입: () => Date | null

    setSystemTime을 사용하여 설정된 mock 현재 날짜를 반환합니다. 날짜가 mock되지 않은 경우 null을 반환합니다.

vi.getRealSystemTime ​

  • 타입: () => number

    vi.useFakeTimers를 사용하는 경우 Date.now 호출이 mock됩니다. 밀리초 단위의 실제 시간을 가져와야 하는 경우 이 함수를 호출할 수 있습니다.

vi.hoisted ​

  • 타입: <T>(factory: () => T) => T

  • 버전: Vitest 0.31.0 이후

    ES 모듈의 모든 정적 import 문은 파일 맨 위로 호이스팅(hoisting)되므로, import문 전에 정의된 코드는 실제로 import문이 평가된 후에 실행됩니다.

    그러나 모듈을 import하기 전에 날짜를 mock하는 것과 같이 특정 부작용을 발생시키는 것이 유용할 수 있습니다.

    이러한 제한 사항을 해결하려면 정적 import를 다음과 같이 동적 import로 다시 작성할 수 있습니다.

    diff
    callFunctionWithSideEffect()
    - import { value } from './some/module.ts'
    + const { value } = await import('./some/module.ts')

    vitest를 실행할 때 vi.hoisted 메서드를 사용하여 이를 자동으로 수행할 수 있습니다.

    diff
    - callFunctionWithSideEffect()
    import { value } from './some/module.ts'
    + vi.hoisted(() => callFunctionWithSideEffect())

    이 메서드는 팩토리 함수에서 반환된 값을 반환합니다. 로컬로 정의된 변수에 쉽게 접근해야 하는 경우 vi.mock 팩토리 함수에서 해당 값을 사용할 수 있습니다.

    ts
    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);

vi.mock ​

  • 타입: (path: string, factory?: () => unknown) => void

    지정된 path에서 import된 모든 모듈을 다른 모듈로 대체합니다. 경로 내에서 구성된 Vite 별칭을 사용할 수 있습니다. vi.mock에 대한 호출은 호이스팅(hoisting)되므로 호출 위치는 중요하지 않습니다. 항상 모든 import 전에 실행됩니다. 스코프 밖의 변수를 참조해야 하는 경우, vi.hoisted 내부에 변수를 정의하고 vi.mock 내부에서 참조할 수 있습니다.

    WARNING

    vi.mock은 import 키워드로 import된 모듈에만 작동합니다. require에서는 작동하지 않습니다.

    Vitest는 vi.mock을 호이스팅(hoisting)하기 위해 파일을 정적으로 분석합니다. 즉, vitest 패키지에서 직접 import되지 않은 vi (예: 일부 유틸리티 파일에서)는 사용할 수 없습니다. 이를 해결하려면 항상 vitest에서 import된 vi와 함께 vi.mock을 사용하거나 globals 구성 옵션을 활성화하십시오.

    WARNING

    모듈 mock은 현재 브라우저 모드에서 지원되지 않습니다. GitHub 이슈에서 이 기능을 추적할 수 있습니다.

    factory가 정의된 경우 모든 import는 해당 결과를 반환합니다. Vitest는 팩토리 함수를 한 번만 호출하고 vi.unmock 또는 vi.doUnmock이 호출될 때까지 모든 후속 import에 대해 결과를 캐시합니다.

    jest와 달리 팩토리 함수는 비동기적일 수 있으므로 vi.importActual 또는 첫 번째 인수로 받은 헬퍼를 내부에서 사용하여 원래 모듈을 가져올 수 있습니다.

    ts
    vi.mock('./path/to/module.js', async importOriginal => {
      const mod = await importOriginal();
      return {
        ...mod,
        // replace some exports
        namedExport: vi.fn(),
      };
    });

    WARNING

    vi.mock은 파일의 최상단으로 호이스팅(hoisting)됩니다 (즉, 끌어올려집니다). 즉, 작성하는 위치 (예: beforeEach 또는 test 내부)에 관계없이 실제로 그 전에 호출됩니다.

    이는 또한 팩토리 함수 외부에서 정의된 변수를 팩토리 함수 내부에서 사용할 수 없음을 의미합니다.

    팩토리 함수 내부에서 변수를 사용해야 하는 경우 vi.doMock을 사용해 보십시오. 동일한 방식으로 작동하지만 호이스팅(hoisting)되지 않습니다. 이후 import만 mock합니다.

    vi.mock 전에 선언된 경우 vi.hoisted 메서드에 의해 정의된 변수를 참조할 수도 있습니다.

    ts
    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);

    WARNING

    default export를 사용하는 모듈을 mock하는 경우, 반환되는 팩토리 함수 객체 내에 default 키를 반드시 포함해야 합니다. 이는 ES 모듈 관련 주의 사항이므로 jest는 CommonJS 모듈을 사용하므로 jest 설명서와 다를 수 있습니다. 예를 들어,

    ts
    vi.mock('./path/to/module.js', () => {
      return {
        default: { myDefaultKey: vi.fn() },
        namedExport: vi.fn(),
        // etc...
      };
    });

    mock하려는 파일과 함께 __mocks__ 폴더가 있고 팩토리 함수가 제공되지 않은 경우 Vitest는 __mocks__ 하위 폴더에서 동일한 이름의 파일을 찾아 실제 모듈로 사용하려고 시도합니다. 종속성을 mock하는 경우 Vitest는 프로젝트의 루트 (기본값은 process.cwd())에서 __mocks__ 폴더를 찾으려고 시도합니다. deps.moduleDirectories 구성 옵션을 통해 Vitest에 종속성이 있는 위치를 알릴 수 있습니다.

    예를 들어, 다음과 같은 파일 구조가 있습니다.

    - __mocks__
      - axios.js
    - src
      __mocks__
        - increment.js
      - increment.js
    - tests
      - increment.test.js

    팩토리 함수가 제공되지 않은 테스트 파일에서 vi.mock을 호출하면 모듈로 사용할 __mocks__ 폴더에서 파일을 찾습니다.

    ts
    // increment.test.js
    import { vi } from 'vitest';
    
    // axios는 `__mocks__/axios.js`의 기본 내보내기(default export)입니다.
    import axios from 'axios';
    
    // increment는 `src/__mocks__/increment.js`의 명명된 내보내기(named export)입니다.
    import { increment } from '../increment.js';
    
    vi.mock('axios');
    vi.mock('../increment.js');
    
    axios.get(`/apples/${increment(1)}`);

    WARNING

    vi.mock을 호출하지 않으면 모듈이 자동으로 mock되지 않습니다. Jest의 자동 mock 동작을 복제하려면 setupFiles 내에서 필요한 각 모듈에 대해 vi.mock을 호출할 수 있습니다.

    __mocks__ 폴더 또는 제공된 팩토리 함수가 없는 경우 Vitest는 원래 모듈을 import하고 모든 내보내기(export)를 자동으로 mock합니다. 적용되는 규칙은 알고리즘을 참조하십시오.

vi.doMock ​

  • 타입: (path: string, factory?: () => unknown) => void

    vi.mock과 동일하지만 파일 맨 위로 호이스팅(hoisting)되지 않으므로 전역 파일 스코프에서 변수를 참조할 수 있습니다. 이후의 동적 import는 mock됩니다. 이는 이 호출 전에 import된 모듈은 mock하지 않습니다.

ts
// ./increment.js
export function increment(number) {
  return number + 1;
}
ts
import { beforeEach, test } from 'vitest';
import { increment } from './increment.js';

// vi.doMock이 아직 호출되지 않았으므로 모듈이 mock되지 않았습니다.
increment(1) === 2;

let mockedIncrement = 100;

beforeEach(() => {
  // 팩토리 함수 내부에서 변수에 접근할 수 있습니다.
  vi.doMock('./increment.js', () => ({ increment: () => ++mockedIncrement }));
});

test('다음 모듈 import는 mock된 모듈을 import합니다.', async () => {
  // 원래 import는 `vi.doMock` 호출 이후에 평가되기 때문에 mock되지 않았습니다.
  expect(increment(1)).toBe(2);
  const { increment: mockedIncrement } = await import('./increment.js');
  // 새로운 동적 import는 mock된 모듈을 반환합니다.
  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>를 반환 값으로 예상합니다.

    ts
    import example from './example.js';
    
    vi.mock('./example.js');
    
    test('1 + 1은 2와 같습니다.', async () => {
      vi.mocked(example.calc).mockRestore();
    
      const res = example.calc(1, '+', 1);
    
      expect(res).toBe(2);
    });

vi.importActual ​

  • 타입: <T>(path: string) => Promise<T>

    모듈을 import할 때 mock 여부에 대한 검사를 건너뜁니다. 모듈을 부분적으로 mock하려는 경우 유용할 수 있습니다.

    ts
    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>>

    모든 속성 (중첩된 속성 포함)이 mock된 모듈을 import합니다. vi.mock과 동일한 규칙을 따릅니다. 적용되는 규칙은 알고리즘을 참조하십시오.

vi.resetAllMocks ​

모든 스파이(spy)에서 .mockReset()을 호출합니다. 이렇게 하면 mock 히스토리가 지워지고 구현이 빈 함수로 초기화됩니다 ( undefined 반환).

vi.resetConfig ​

  • 타입: RuntimeConfig

    vi.setConfig이 이전에 호출된 경우 설정을 원래 상태로 되돌립니다.

vi.resetModules ​

  • 타입: () => Vitest

    모든 모듈의 캐시를 삭제하여 모듈 레지스트리를 초기화합니다. 이렇게 하면 모듈을 다시 import할 때 모듈을 다시 평가할 수 있습니다. 최상위 import는 다시 평가할 수 없습니다. 로컬 상태가 테스트 간에 충돌하는 모듈을 격리하는 데 유용할 수 있습니다.

    ts
    import { vi } from 'vitest';
    
    import { data } from './data.js'; // beforeEach 테스트에서 다시 평가되지 않습니다.
    
    beforeEach(() => {
      vi.resetModules();
    });
    
    test('상태 변경', async () => {
      const mod = await import('./some/path.js'); // 다시 평가됩니다.
      mod.changeLocalState('new value');
      expect(mod.getLocalState()).toBe('new value');
    });
    
    test('모듈이 이전 상태를 유지합니다.', async () => {
      const mod = await import('./some/path.js'); // 다시 평가됩니다.
      expect(mod.getLocalState()).toBe('old value');
    });

WARNING

mock 레지스트리를 재설정하지 않습니다. mock 레지스트리를 지우려면 vi.unmock 또는 vi.doUnmock을 사용하십시오.

vi.restoreAllMocks ​

모든 스파이(spy)에서 .mockRestore()을 호출합니다. 이렇게 하면 mock 히스토리가 지워지고 구현이 원래 상태로 재설정됩니다.

vi.stubEnv ​

  • 타입: (name: string, value: string) => Vitest

  • 버전: Vitest 0.26.0 이후

    process.env 및 import.meta.env에서 환경 변수의 값을 변경합니다. vi.unstubAllEnvs를 호출하면 값을 복원할 수 있습니다.

ts
import { vi } from 'vitest';

// `process.env.NODE_ENV` 및 `import.meta.env.NODE_ENV`
// `vi.stubEnv` 호출 전에는 "development"입니다.

vi.stubEnv('NODE_ENV', 'production');

process.env.NODE_ENV === 'production';
import.meta.env.NODE_ENV === 'production';
// 다른 env는 변경하지 않습니다.
import.meta.env.MODE === 'development';

TIP

값을 직접 할당하여 변경할 수도 있지만 vi.unstubAllEnvs를 사용하여 이전 값을 복원할 수는 없습니다.

ts
import.meta.env.MODE = 'test';

vi.unstubAllEnvs ​

  • 타입: () => Vitest

  • 버전: Vitest 0.26.0 이후

    vi.stubEnv를 통해 변경된 모든 import.meta.env 및 process.env 값을 원래 값으로 복원합니다. unstubAllEnvs가 처음 호출될 때 Vitest는 현재 값을 저장하고, 이후 unstubAllEnvs가 호출될 때 저장된 값으로 되돌립니다.

ts
import { vi } from 'vitest';

// `process.env.NODE_ENV` 및 `import.meta.env.NODE_ENV`
// stubEnv 호출 전에는 "development"입니다.

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();

// 첫 번째 "stubEnv" 호출 전에 저장된 값으로 복원됩니다.
process.env.NODE_ENV === 'development';
import.meta.env.NODE_ENV === 'development';

vi.stubGlobal ​

  • 타입: (name: string | number | symbol, value: unknown) => Vitest

    전역 변수의 값을 지정된 값으로 변경합니다. vi.unstubAllGlobals를 호출하여 원래 값으로 복원할 수 있습니다.

ts
import { vi } from 'vitest';

// `innerWidth`는 `stubGlobal` 호출 전에는 "0"입니다.

vi.stubGlobal('innerWidth', 100);

innerWidth === 100;
globalThis.innerWidth === 100;
// jsdom 또는 happy-dom을 사용하는 경우
window.innerWidth === 100;

TIP

globalThis 또는 window ( jsdom 또는 happy-dom 환경을 사용하는 경우)에 직접 값을 할당하여 변경할 수도 있지만, 이 경우 vi.unstubAllGlobals를 사용하여 원래 값을 복원할 수 없습니다.

ts
globalThis.innerWidth = 100;
// jsdom 또는 happy-dom을 사용하는 경우
window.innerWidth = 100;

vi.unstubAllGlobals ​

  • 타입: () => Vitest

  • 버전: Vitest 0.26.0 이후

    vi.stubGlobal을 통해 변경된 globalThis/global (및 window/top/self/parent, jsdom 또는 happy-dom 환경을 사용하는 경우)의 모든 전역 값을 원래 값으로 복원합니다. unstubAllGlobals가 처음 호출될 때 Vitest는 현재 값을 저장하고, 이후 unstubAllGlobals가 호출될 때 저장된 값으로 되돌립니다.

ts
import { vi } from 'vitest';

const Mock = vi.fn();

// IntersectionObserver는 "stubGlobal" 호출 전에는 "undefined"입니다.

vi.stubGlobal('IntersectionObserver', Mock);

IntersectionObserver === Mock;
global.IntersectionObserver === Mock;
globalThis.IntersectionObserver === Mock;
// jsdom 또는 happy-dom을 사용하는 경우
window.IntersectionObserver === Mock;

vi.unstubAllGlobals();

globalThis.IntersectionObserver === undefined;
'IntersectionObserver' in globalThis === false;
// ReferenceError를 발생시킵니다. 정의되지 않았기 때문입니다.
IntersectionObserver === undefined;

vi.runAllTicks ​

  • 타입: () => Vitest

    process.nextTick을 통해 큐에 추가된 모든 마이크로태스크를 실행합니다. 이는 또한 자체적으로 예약된 모든 마이크로태스크도 실행합니다.

vi.runAllTimers ​

  • 타입: () => Vitest

    이 메서드는 타이머 큐가 빌 때까지 보류 중인 모든 타이머를 실행합니다. 즉, runAllTimers 실행 중에 예약된 타이머도 실행됩니다. 무한 간격으로 설정된 타이머가 있는 경우, 10,000번 시도 후 오류가 발생합니다. 다음은 1, 2, 3을 콘솔에 출력하는 예제입니다.

    ts
    let i = 0;
    setTimeout(() => console.log(++i));
    const interval = setInterval(() => {
      console.log(++i);
      if (i === 3) clearInterval(interval);
    }, 50);
    
    vi.runAllTimers();

vi.runAllTimersAsync ​

  • 타입: () => Promise<Vitest>

    이 메서드는 타이머 큐가 빌 때까지 보류 중인 모든 타이머를 비동기적으로 실행합니다. 즉, runAllTimersAsync 실행 중에 예약된 비동기 타이머도 실행됩니다. 무한 간격으로 설정된 타이머가 있는 경우, 10,000번 시도 후 오류가 발생합니다. 다음은 result를 콘솔에 출력하는 예제입니다.

    ts
    setTimeout(async () => {
      console.log(await Promise.resolve('result'));
    }, 100);
    
    await vi.runAllTimersAsync();

vi.runOnlyPendingTimers ​

  • 타입: () => Vitest

    이 메서드는 vi.useFakeTimers() 호출 이후에 예약된 모든 타이머를 실행합니다. 실행 중에 예약된 타이머는 실행되지 않습니다. 다음은 1만 콘솔에 출력하는 예제입니다.

    ts
    let i = 0;
    setInterval(() => console.log(++i), 50);
    
    vi.runOnlyPendingTimers();

vi.runOnlyPendingTimersAsync ​

  • 타입: () => Promise<Vitest>

    이 메서드는 vi.useFakeTimers() 호출 이후에 예약된 모든 타이머를 비동기적으로 실행합니다 (비동기 타이머 포함). 실행 중에 예약된 타이머는 실행되지 않습니다. 다음은 2, 3, 3, 1을 콘솔에 출력하는 예제입니다.

    ts
    setTimeout(() => {
      console.log(1);
    }, 100);
    setTimeout(() => {
      Promise.resolve().then(() => {
        console.log(2);
        setInterval(() => {
          console.log(3);
        }, 40);
      });
    }, 10);
    
    await vi.runOnlyPendingTimersAsync();

vi.setSystemTime ​

  • 타입: (date: string | number | Date) => void

    시스템 시간을 지정된 날짜로 설정합니다. 이후 모든 Date 호출은 이 날짜를 기준으로 합니다.

    코드 내부에서 luxon과 같이 현재 시간에 의존하는 로직을 테스트할 때 유용합니다.

    ts
    const date = new Date(1998, 11, 19);
    
    vi.useFakeTimers();
    vi.setSystemTime(date);
    
    expect(Date.now()).toBe(date.valueOf());
    
    vi.useRealTimers();

vi.setConfig ​

  • 타입: RuntimeConfig

    현재 테스트 파일의 설정을 업데이트합니다. 이 설정은 테스트 실행 시에만 적용됩니다.

vi.spyOn ​

  • 타입: <T, K extends keyof T>(object: T, method: K, accessType?: 'get' | 'set') => MockInstance

    객체의 메서드 또는 getter/setter에 대한 스파이 함수를 생성합니다.

    ts
    let apples = 0;
    const cart = {
      getApples: () => 13,
    };
    
    const spy = vi.spyOn(cart, 'getApples').mockImplementation(() => apples);
    apples = 1;
    
    expect(cart.getApples()).toBe(1);
    
    expect(spy).toHaveBeenCalled();
    expect(spy).toHaveReturnedWith(1);

vi.stubGlobal ​

  • 타입: (key: keyof globalThis & Window, value: any) => Vitest

    전역 변수에 값을 할당합니다. jsdom 또는 happy-dom을 사용하는 경우 window 객체에도 값을 할당합니다.

    자세한 내용은 "전역 모의" 섹션을 참조하십시오.

vi.unmock ​

  • 타입: (path: string) => void

    모의(mock) 레지스트리에서 모듈을 제거합니다. 이후 해당 모듈에 대한 import는 이전에 모의되었더라도 원래 모듈을 반환합니다. 이 호출은 호이스팅되어 파일 맨 위로 이동하므로, 예를 들어 setupFiles에 정의된 모듈만 언모킹됩니다.

vi.doUnmock ​

  • 타입: (path: string) => void

    vi.unmock과 동일하지만 파일의 맨 위로 호이스팅되지 않습니다. 다음에 해당 모듈을 import하면 모의된 모듈 대신 실제 모듈을 가져옵니다. 이미 가져온 모듈은 언모킹되지 않습니다.

ts
// ./increment.js
export function increment(number) {
  return number + 1;
}
ts
import { increment } from './increment.js';

// increment는 vi.mock이 호이스팅되기 때문에 이미 모의되었습니다.
increment(1) === 100;

// 이는 호이스팅되고 팩토리는 1행의 가져오기 전에 호출됩니다.
vi.mock('./increment.js', () => ({ increment: () => 100 }));

// 모든 호출이 모의되고 `increment`는 항상 100을 반환합니다.
increment(1) === 100;
increment(30) === 100;

// 이는 호이스팅되지 않으므로 다른 가져오기는 언모킹된 모듈을 반환합니다.
vi.doUnmock('./increment.js');

// 이는 `vi.doUnmock`이 모듈을 다시 평가하지 않기 때문에 여전히 100을 반환합니다.
increment(1) === 100;
increment(30) === 100;

// 다음 가져오기는 언모킹되었으며 이제 `increment`는 count + 1을 반환하는 원래 함수입니다.
const { increment: unmockedIncrement } = await import('./increment.js');

unmockedIncrement(1) === 2;
unmockedIncrement(30) === 31;

vi.useFakeTimers ​

  • 타입: () => Vitest

    타이머 모의를 활성화하려면 이 메서드를 호출해야 합니다. 이 메서드는 vi.useRealTimers()가 호출될 때까지 타이머(setTimeout, setInterval, clearTimeout, clearInterval, nextTick, setImmediate, clearImmediate 및 Date 등)에 대한 모든 후속 호출을 래핑합니다.

    --no-threads를 사용하여 node:child_process 내부에서 Vitest를 실행할 때는 nextTick 모의가 지원되지 않습니다. NodeJS는 node:child_process에서 내부적으로 process.nextTick을 사용하며, 모의되면 중단됩니다. --threads를 사용하여 Vitest를 실행할 때는 nextTick 모의가 지원됩니다.

    구현은 내부적으로 @sinonjs/fake-timers를 기반으로 합니다.

    TIP

    0.35.0 버전부터 vi.useFakeTimers()는 더 이상 자동으로 process.nextTick을 모의하지 않습니다. toFake 인수에 옵션을 지정하여 여전히 모의할 수 있습니다. 예: vi.useFakeTimers({ toFake: ['nextTick'] }).

vi.isFakeTimers ​

  • 타입: () => boolean

  • 버전: Vitest 0.34.5 이후

    가짜 타이머가 활성화된 경우 true를 반환합니다.

vi.useRealTimers ​

  • 타입: () => Vitest

    타이머 모의 사용이 끝나면 이 메서드를 호출하여 모의된 타이머를 실제 구현으로 되돌릴 수 있습니다. 이전에 실행된 모든 타이머는 복원되지 않습니다.

vi.waitFor ​

  • 타입: <T>(callback: WaitForCallback<T>, options?: number | WaitForOptions) => Promise<T>
  • 버전: Vitest 0.34.5 이후

콜백 함수가 성공적으로 실행될 때까지 기다립니다. 콜백 함수가 오류를 발생시키거나, 거부된 Promise를 반환하면 성공하거나 시간 초과될 때까지 계속 재시도합니다.

이는 예를 들어 서버를 시작하고 시작될 때까지 기다려야 하는 경우와 같이 비동기 작업이 완료될 때까지 기다려야 할 때 유용합니다.

ts
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, // 기본값은 1000입니다.
      interval: 20, // 기본값은 50입니다.
    }
  );
  expect(server.isReady).toBe(true);
});

비동기 콜백에도 사용할 수 있습니다.

ts
// @vitest-environment jsdom

import { expect, test, vi } from 'vitest';
import { getDOMElementAsync, populateDOMAsync } from './dom.js';

test('Element exists in a DOM', async () => {
  // DOM 채우기 시작
  populateDOMAsync();

  const element = await vi.waitFor(
    async () => {
      // 요소가 존재할 때까지 가져오려고 시도합니다.
      const element = (await getDOMElementAsync()) as HTMLElement | null;
      expect(element).toBeTruthy();
      expect(element.dataset.initialized).toBeTruthy();
      return element;
    },
    {
      timeout: 500, // 기본값은 1000입니다.
      interval: 20, // 기본값은 50입니다.
    }
  );
  expect(element).toBeInstanceOf(HTMLElement);
});

vi.useFakeTimers가 사용되는 경우 vi.waitFor는 각 검사 콜백에서 자동으로 vi.advanceTimersByTime(interval)을 호출합니다.

vi.waitUntil ​

  • 타입: <T>(callback: WaitUntilCallback<T>, options?: number | WaitUntilOptions) => Promise<T>
  • 버전: Vitest 0.34.5 이후

vi.waitFor와 유사하지만 콜백이 오류를 발생시키면 즉시 실행이 중단되고 오류 메시지가 표시됩니다. 콜백 함수가 falsy 값을 반환하면 truthy 값이 반환될 때까지 다음 검사를 계속합니다. 이는 다음 단계를 수행하기 전에 특정 조건이 충족될 때까지 기다려야 할 때 유용합니다.

다음 예제를 살펴보세요. vi.waitUntil을 사용하여 페이지에 요소가 나타날 때까지 기다린 다음 해당 요소에 대한 작업을 수행할 수 있습니다.

ts
import { expect, test, vi } from 'vitest';

test('Element render correctly', async () => {
  const element = await vi.waitUntil(() => document.querySelector('.element'), {
    timeout: 500, // 기본값은 1000입니다.
    interval: 20, // 기본값은 50입니다.
  });

  // 해당 요소에 대한 작업을 수행합니다.
  expect(element.querySelector('.element-child')).toBeTruthy();
});
Pager
이전Mock 함수
다음expect

MIT 라이선스 하에 배포되었습니다.

Copyright (c) 2024 Mithril Contributors

https://v0.vitest.dev/api/vi

MIT 라이선스 하에 배포되었습니다.

Copyright (c) 2024 Mithril Contributors