expect
아래 타입 시그니처에 사용되는 타입은 다음과 같습니다.
type Awaitable<T> = T | PromiseLike<T>;
expect
는 단언(assertion)을 생성하는 데 사용됩니다. 이 컨텍스트에서 단언
은 특정 조건을 검증하기 위해 호출되는 함수입니다. Vitest는 기본적으로 chai
단언을 제공하며, chai
를 기반으로 구축된 Jest
호환 단언도 제공합니다. Jest
와 달리 Vitest는 두 번째 인수로 메시지를 지원합니다. 단언이 실패하면 해당 메시지가 오류 메시지로 표시됩니다.
export interface ExpectStatic
extends Chai.ExpectStatic,
AsymmetricMatchersContaining {
<T>(actual: T, message?: string): Assertion<T>;
extend: (expects: MatchersObject) => void;
anything: () => any;
any: (constructor: unknown) => any;
getState: () => MatcherState;
setState: (state: Partial<MatcherState>) => void;
not: AsymmetricMatchersContaining;
}
예를 들어, 이 코드는 input
값이 2
와 같다고 단언합니다. 같지 않으면 단언이 오류를 발생시키고 테스트가 실패합니다.
import { expect } from 'vitest';
const input = Math.sqrt(4);
expect(input).to.equal(2); // chai API
expect(input).toBe(2); // jest API
기술적으로 이 예제는 test
함수를 사용하지 않기 때문에 콘솔에는 Vitest의 테스트 결과 출력 대신 Node.js 오류가 표시됩니다. test
에 대해 자세히 알아보려면 Test API Reference를 참조하세요.
또한 expect
는 나중에 설명할 매처(matcher) 함수 등에 정적으로 접근하는 데 사용될 수 있습니다.
WARNING
expect
는 표현식에 타입 오류가 없으면 타입 검사에 영향을 미치지 않습니다. Vitest를 타입 검사 도구로 사용하려면 expectTypeOf
또는 assertType
를 사용하세요.
soft
- 타입:
ExpectStatic & (actual: any) => Assertions
expect.soft
는 expect
와 유사하게 작동하지만, 단언 실패 시 테스트 실행을 종료하는 대신 계속 실행하며 해당 실패를 테스트 실패로 기록합니다. 테스트가 완료될 때까지 테스트 중에 발생한 모든 오류가 표시됩니다.
import { expect, test } from 'vitest';
test('expect.soft test', () => {
expect.soft(1 + 1).toBe(3); // 테스트를 실패로 표시하고 계속 진행
expect.soft(1 + 2).toBe(4); // 테스트를 실패로 표시하고 계속 진행
});
// 리포터는 실행이 끝날 때 두 오류를 모두 보고합니다.
expect
와 함께 사용할 수도 있습니다. expect
단언이 실패하면 테스트가 종료되고 이전의 모든 오류가 출력됩니다.
import { expect, test } from 'vitest';
test('expect.soft test', () => {
expect.soft(1 + 1).toBe(3); // 테스트를 실패로 표시하고 계속 진행
expect(1 + 2).toBe(4); // 실패하고 테스트를 종료하며, 이전의 모든 오류가 출력됩니다.
expect.soft(1 + 3).toBe(5); // 실행되지 않음
});
WARNING
expect.soft
는 test
함수 내부에서만 사용할 수 있습니다.
poll
interface ExpectPoll extends ExpectStatic {
(actual: () => T, options: { interval; timeout; message }): Promise<
Assertions<T>
>;
}
expect.poll
은 _단언_이 성공할 때까지 재시도합니다. interval
및 timeout
옵션을 설정하여 Vitest가 expect.poll
콜백을 몇 번 다시 실행해야 하는지 구성할 수 있습니다.
expect.poll
콜백 내부에서 오류가 발생하면 Vitest는 타임아웃이 만료될 때까지 다시 시도합니다.
import { expect, test } from 'vitest';
test('element exists', async () => {
asyncInjectElement();
await expect.poll(() => document.querySelector('.element')).toBeTruthy();
});
WARNING
expect.poll
은 모든 단언을 비동기적으로 처리하므로 await
해야 합니다. Vitest 3부터는 await
를 생략하면 테스트가 실패하고 경고가 표시됩니다.
expect.poll
은 여러 매처와 함께 작동하지 않습니다.
- 스냅샷 매처는 항상 성공하므로 지원되지 않습니다. 조건이 불안정할 수 있다면
vi.waitFor
를 사용하여 먼저 해결하는 것을 고려하세요.
import { expect, vi } from 'vitest';
const flakyValue = await vi.waitFor(() => getFlakyValue());
expect(flakyValue).toMatchSnapshot();
.resolves
및.rejects
는 지원되지 않습니다.expect.poll
은 조건이 비동기식인 경우 이미await
합니다.toThrow
및 해당 별칭은 지원되지 않습니다.expect.poll
조건은 매처가 값을 받기 전에 항상 해결되기 때문입니다.
not
not
을 사용하면 단언을 부정합니다. 예를 들어, 이 코드는 input
값이 2
와 같지 않다고 단언합니다. 같으면 단언이 오류를 발생시키고 테스트가 실패합니다.
import { expect, test } from 'vitest';
const input = Math.sqrt(16);
expect(input).not.to.equal(2); // chai API
expect(input).not.toBe(2); // jest API
toBe
- 타입:
(value: any) => Awaitable<void>
toBe
는 원시 값이 같은지 또는 객체가 동일한 참조를 공유하는지 단언하는 데 사용됩니다. 이는 expect(Object.is(3, 3)).toBe(true)
를 호출하는 것과 동일합니다. 객체가 동일하지 않지만 구조가 동일한지 확인하려면 toEqual
을 사용할 수 있습니다.
예를 들어, 아래 코드는 상인이 사과 13개를 가지고 있는지 확인합니다.
import { expect, test } from 'vitest';
const stock = {
type: 'apples',
count: 13,
};
test('stock has 13 apples', () => {
expect(stock.type).toBe('apples');
expect(stock.count).toBe(13);
});
test('stocks are the same', () => {
const refStock = stock; // 동일한 참조
expect(stock).toBe(refStock);
});
부동 소수점 숫자와 함께 toBe
를 사용하지 마십시오. JavaScript는 부동 소수점 숫자를 반올림하므로 0.1 + 0.2
는 엄격하게 0.3
이 아닙니다. 부동 소수점 숫자를 안정적으로 단언하려면 toBeCloseTo
단언을 사용하십시오.
toBeCloseTo
- 타입:
(value: number, numDigits?: number) => Awaitable<void>
부동 소수점 숫자를 비교하려면 toBeCloseTo
를 사용하십시오. 선택적 numDigits
인수는 소수점 _뒤_에 확인할 자릿수를 제한합니다. 예를 들어:
import { expect, test } from 'vitest';
test.fails('decimals are not equal in javascript', () => {
expect(0.2 + 0.1).toBe(0.3); // 0.2 + 0.1은 0.30000000000000004입니다.
});
test('decimals are rounded to 5 after the point', () => {
// 0.2 + 0.1은 0.30000 | "000000000004"가 제거됨
expect(0.2 + 0.1).toBeCloseTo(0.3, 5);
// 0.30000000000000004에서 아무것도 제거되지 않음
expect(0.2 + 0.1).not.toBeCloseTo(0.3, 50);
});
toBeDefined
- 타입:
() => Awaitable<void>
toBeDefined
는 값이 undefined
가 아님을 단언합니다. 함수가 값을 반환했는지 확인할 때 유용합니다.
import { expect, test } from 'vitest';
function getApples() {
return 3;
}
test('function returned something', () => {
expect(getApples()).toBeDefined();
});
toBeUndefined
- 타입:
() => Awaitable<void>
toBeDefined
의 반대인 toBeUndefined
는 값이 undefined
임을 단언합니다. 함수가 값을 반환하지 않았는지 확인할 때 유용합니다.
import { expect, test } from 'vitest';
function getApplesFromStock(stock: string) {
if (stock === 'Bill') {
return 13;
}
}
test("mary doesn't have a stock", () => {
expect(getApplesFromStock('Mary')).toBeUndefined();
});
toBeTruthy
- 타입:
() => Awaitable<void>
toBeTruthy
는 값이 불리언으로 변환될 때 true
인지 단언합니다. 값 자체보다는 true
로 변환될 수 있는지 여부가 중요할 때 유용합니다.
예를 들어, 이 코드를 사용하면 stocks.getInfo
의 반환 값은 중요하지 않습니다. 복잡한 객체, 문자열 또는 다른 어떤 것일 수도 있지만, 코드는 여전히 작동합니다.
import { Stocks } from './stocks.js';
const stocks = new Stocks();
stocks.sync('Bill');
if (stocks.getInfo('Bill')) {
stocks.sell('apples', 'Bill');
}
따라서 stocks.getInfo
가 truthy인지 테스트하려면 다음과 같이 작성할 수 있습니다.
import { expect, test } from 'vitest';
import { Stocks } from './stocks.js';
const stocks = new Stocks();
test('if we know Bill stock, sell apples to him', () => {
stocks.sync('Bill');
expect(stocks.getInfo('Bill')).toBeTruthy();
});
JavaScript의 모든 것은 false
, null
, undefined
, NaN
, 0
, -0
, 0n
, ""
및 document.all
을 제외하고는 truthy입니다.
toBeFalsy
- 타입:
() => Awaitable<void>
toBeFalsy
는 값이 불리언으로 변환될 때 false
인지 단언합니다. 값 자체보다는 false
로 변환될 수 있는지 여부가 중요할 때 유용합니다.
예를 들어, 이 코드를 사용하면 stocks.stockFailed
의 반환 값은 중요하지 않습니다. 어떤 falsy 값을 반환할 수도 있지만 코드는 여전히 작동합니다.
import { Stocks } from './stocks.js';
const stocks = new Stocks();
stocks.sync('Bill');
if (!stocks.stockFailed('Bill')) {
stocks.sell('apples', 'Bill');
}
따라서 stocks.stockFailed
가 falsy인지 테스트하려면 다음과 같이 작성할 수 있습니다.
import { expect, test } from 'vitest';
import { Stocks } from './stocks.js';
const stocks = new Stocks();
test("if Bill stock hasn't failed, sell apples to him", () => {
stocks.syncStocks('Bill');
expect(stocks.stockFailed('Bill')).toBeFalsy();
});
JavaScript의 모든 것은 false
, null
, undefined
, NaN
, 0
, -0
, 0n
, ""
및 document.all
을 제외하고는 truthy입니다.
toBeNull
- 타입:
() => Awaitable<void>
toBeNull
은 단순히 어떤 것이 null
인지 단언합니다. .toBe(null)
의 별칭입니다.
import { expect, test } from 'vitest';
function apples() {
return null;
}
test("we don't have apples", () => {
expect(apples()).toBeNull();
});
toBeNaN
- 타입:
() => Awaitable<void>
toBeNaN
은 단순히 값이 NaN
인지 단언합니다. .toBe(NaN)
의 별칭입니다.
import { expect, test } from 'vitest';
let i = 0;
function getApplesCount() {
i++;
return i > 1 ? Number.NaN : i;
}
test('getApplesCount has some unusual side effects...', () => {
expect(getApplesCount()).not.toBeNaN();
expect(getApplesCount()).toBeNaN();
});
toBeOneOf
- 타입:
(sample: Array<any>) => any
toBeOneOf
는 값이 제공된 배열의 값 중 하나와 일치하는지 단언합니다.
import { expect, test } from 'vitest';
test('fruit is one of the allowed values', () => {
expect(fruit).toBeOneOf(['apple', 'banana', 'orange']);
});
이 비대칭 매처는 null
또는 undefined
일 수 있는 선택적 속성을 테스트할 때 특히 유용합니다.
test('optional properties can be null or undefined', () => {
const user = {
firstName: 'John',
middleName: undefined,
lastName: 'Doe',
};
expect(user).toEqual({
firstName: expect.any(String),
middleName: expect.toBeOneOf([expect.any(String), undefined]),
lastName: expect.any(String),
});
});
TIP
이 매처와 함께 expect.not
을 사용하여 값이 제공된 옵션 중 어느 것과도 일치하지 않도록 할 수 있습니다.
toBeTypeOf
- 타입:
(c: 'bigint' | 'boolean' | 'function' | 'number' | 'object' | 'string' | 'symbol' | 'undefined') => Awaitable<void>
toBeTypeOf
는 실제 값이 예상된 타입과 일치하는지 단언합니다.
import { expect, test } from 'vitest';
const actual = 'stock';
test('stock is type of string', () => {
expect(actual).toBeTypeOf('string');
});
toBeInstanceOf
- 타입:
(c: any) => Awaitable<void>
toBeInstanceOf
는 실제 값이 특정 클래스의 인스턴스인지 단언합니다.
import { expect, test } from 'vitest';
import { Stocks } from './stocks.js';
const stocks = new Stocks();
test('stocks are instance of Stocks', () => {
expect(stocks).toBeInstanceOf(Stocks);
});
toBeGreaterThan
- 타입:
(n: number | bigint) => Awaitable<void>
toBeGreaterThan
은 실제 값이 주어진 값보다 큰지 단언합니다. 값이 같으면 테스트가 실패합니다.
import { expect, test } from 'vitest';
import { getApples } from './stocks.js';
test('have more then 10 apples', () => {
expect(getApples()).toBeGreaterThan(10);
});
toBeGreaterThanOrEqual
- 타입:
(n: number | bigint) => Awaitable<void>
toBeGreaterThanOrEqual
은 실제 값이 주어진 값보다 크거나 같은지 단언합니다.
import { expect, test } from 'vitest';
import { getApples } from './stocks.js';
test('have 11 apples or more', () => {
expect(getApples()).toBeGreaterThanOrEqual(11);
});
toBeLessThan
- 타입:
(n: number | bigint) => Awaitable<void>
toBeLessThan
은 실제 값이 주어진 값보다 작은지 단언합니다. 값이 같으면 테스트가 실패합니다.
import { expect, test } from 'vitest';
import { getApples } from './stocks.js';
test('have less then 20 apples', () => {
expect(getApples()).toBeLessThan(20);
});
toBeLessThanOrEqual
- 타입:
(n: number | bigint) => Awaitable<void>
toBeLessThanOrEqual
은 실제 값이 주어진 값보다 작거나 같은지 단언합니다.
import { expect, test } from 'vitest';
import { getApples } from './stocks.js';
test('have 11 apples or less', () => {
expect(getApples()).toBeLessThanOrEqual(11);
});
toEqual
- 타입:
(received: any) => Awaitable<void>
toEqual
은 실제 값이 예상된 값과 같거나, 객체인 경우 동일한 구조를 갖는지 단언합니다(재귀적으로 비교). toEqual
과 toBe
의 차이점은 이 예제에서 확인할 수 있습니다.
import { expect, test } from 'vitest';
const stockBill = {
type: 'apples',
count: 13,
};
const stockMary = {
type: 'apples',
count: 13,
};
test('stocks have the same properties', () => {
expect(stockBill).toEqual(stockMary);
});
test('stocks are not the same', () => {
expect(stockBill).not.toBe(stockMary);
});
WARNING
Error
객체의 경우 name
, message
, cause
및 AggregateError.errors
와 같은 열거 불가능한 속성도 비교됩니다. Error.cause
의 경우 비교는 비대칭적으로 수행됩니다.
// 성공
expect(new Error('hi', { cause: 'x' })).toEqual(new Error('hi'));
// 실패
expect(new Error('hi')).toEqual(new Error('hi', { cause: 'x' }));
예외가 발생했는지 테스트하려면 toThrowError
단언을 사용하십시오.
toStrictEqual
- 타입:
(received: any) => Awaitable<void>
toStrictEqual
은 실제 값이 예상된 값과 같거나, 객체인 경우 동일한 구조를 가지며(재귀적으로 비교), 동일한 타입인지 단언합니다.
.toEqual
과의 차이점:
undefined
속성을 가진 키도 비교됩니다. 예를 들어,{a: undefined, b: 2}
는.toStrictEqual
을 사용할 때{b: 2}
와 일치하지 않습니다.- 배열의 희소성도 비교됩니다. 예를 들어,
[, 1]
은.toStrictEqual
을 사용할 때[undefined, 1]
과 일치하지 않습니다. - 객체 타입이 동일한지 확인됩니다. 예를 들어, 필드
a
와b
를 가진 클래스 인스턴스는 필드a
와b
를 가진 리터럴 객체와 같지 않습니다.
import { expect, test } from 'vitest';
class Stock {
constructor(type) {
this.type = type;
}
}
test('structurally the same, but semantically different', () => {
expect(new Stock('apples')).toEqual({ type: 'apples' });
expect(new Stock('apples')).not.toStrictEqual({ type: 'apples' });
});
toContain
- 타입:
(received: string) => Awaitable<void>
toContain
은 실제 값이 배열에 포함되어 있는지 단언합니다. toContain
은 문자열이 다른 문자열의 부분 문자열인지도 확인할 수 있습니다. 브라우저와 유사한 환경에서 테스트를 실행하는 경우 이 단언은 클래스가 classList
에 포함되어 있는지 또는 요소가 다른 요소 내부에 포함되어 있는지 확인할 수도 있습니다.
import { expect, test } from 'vitest';
import { getAllFruits } from './stocks.js';
test('the fruit list contains orange', () => {
expect(getAllFruits()).toContain('orange');
const element = document.querySelector('#el');
// 요소에 클래스가 있습니다.
expect(element.classList).toContain('flex');
// 요소가 다른 요소 내부에 있습니다.
expect(document.querySelector('#wrapper')).toContain(element);
});
toContainEqual
- 타입:
(received: any) => Awaitable<void>
toContainEqual
은 특정 구조와 값을 가진 항목이 배열에 포함되어 있는지 단언합니다. 각 요소에 대해 toEqual
처럼 작동합니다.
import { expect, test } from 'vitest';
import { getFruitStock } from './stocks.js';
test('apple available', () => {
expect(getFruitStock()).toContainEqual({ fruit: 'apple', count: 5 });
});
toHaveLength
- 타입:
(received: number) => Awaitable<void>
toHaveLength
는 객체에 .length
속성이 있고 그 값이 특정 숫자와 일치하는지 단언합니다.
import { expect, test } from 'vitest';
test('toHaveLength', () => {
expect('abc').toHaveLength(3);
expect([1, 2, 3]).toHaveLength(3);
expect('').not.toHaveLength(3); // .length가 3이 아님
expect({ length: 3 }).toHaveLength(3);
});
toHaveProperty
- 타입:
(key: any, received?: any) => Awaitable<void>
toHaveProperty
는 주어진 key
에 해당하는 속성이 객체에 존재하는지 단언합니다.
toEqual
매처와 유사하게, 선택적 값 인수를 제공하여 해당 속성 값을 비교할 수도 있습니다. 이를 딥 이퀄리티(deep equality)라고도 합니다.
import { expect, test } from 'vitest';
const invoice = {
isActive: true,
'P.O': '12345',
customer: {
first_name: 'John',
last_name: 'Doe',
location: 'China',
},
total_amount: 5000,
items: [
{
type: 'apples',
quantity: 10,
},
{
type: 'oranges',
quantity: 5,
},
],
};
test('John Doe Invoice', () => {
expect(invoice).toHaveProperty('isActive'); // 키가 존재하는지 단언
expect(invoice).toHaveProperty('total_amount', 5000); // 키가 존재하고 값이 같은지 단언
expect(invoice).not.toHaveProperty('account'); // 이 키가 존재하지 않는지 단언
// 점 표기법을 사용한 딥 참조
expect(invoice).toHaveProperty('customer.first_name');
expect(invoice).toHaveProperty('customer.last_name', 'Doe');
expect(invoice).not.toHaveProperty('customer.location', 'India');
// 키를 포함하는 배열을 사용한 딥 참조
expect(invoice).toHaveProperty('items[0].type', 'apples');
expect(invoice).toHaveProperty('items.0.type', 'apples'); // 점 표기법도 작동
// 키 경로를 포함하는 배열을 사용한 딥 참조
expect(invoice).toHaveProperty(['items', 0, 'type'], 'apples');
expect(invoice).toHaveProperty(['items', '0', 'type'], 'apples'); // 문자열 표기법도 작동
// 키가 딥 참조로 파싱되는 것을 방지하기 위해 키를 배열로 묶습니다.
expect(invoice).toHaveProperty(['P.O'], '12345');
});
toMatch
- 타입:
(received: string | regexp) => Awaitable<void>
toMatch
는 문자열이 정규 표현식 또는 다른 문자열과 일치하는지 단언합니다.
import { expect, test } from 'vitest';
test('top fruits', () => {
expect('top fruits include apple, orange and grape').toMatch(/apple/);
expect('applefruits').toMatch('fruit'); // toMatch는 문자열도 허용합니다.
});
toMatchObject
- 타입:
(received: object | array) => Awaitable<void>
toMatchObject
는 객체가 다른 객체의 속성 부분 집합과 일치하는지 단언합니다.
객체 배열을 전달할 수도 있습니다. 이는 arrayContaining
이 수신된 배열에 추가 요소를 허용하는 것과 달리, 두 배열의 요소 수가 정확히 일치하는지 확인하려는 경우에 유용합니다.
import { expect, test } from 'vitest';
const johnInvoice = {
isActive: true,
customer: {
first_name: 'John',
last_name: 'Doe',
location: 'China',
},
total_amount: 5000,
items: [
{
type: 'apples',
quantity: 10,
},
{
type: 'oranges',
quantity: 5,
},
],
};
const johnDetails = {
customer: {
first_name: 'John',
last_name: 'Doe',
location: 'China',
},
};
test('invoice has john personal details', () => {
expect(johnInvoice).toMatchObject(johnDetails);
});
test('the number of elements must match exactly', () => {
// 객체 배열이 일치하는지 단언
expect([{ foo: 'bar' }, { baz: 1 }]).toMatchObject([
{ foo: 'bar' },
{ baz: 1 },
]);
});
toThrowError
타입:
(received: any) => Awaitable<void>
별칭:
toThrow
toThrowError
는 함수가 호출될 때 오류를 발생시키는지 단언합니다.
특정 오류가 던져지는지 테스트하기 위해 선택적 인수를 제공할 수 있습니다.
RegExp
: 오류 메시지가 패턴과 일치하는지 확인합니다.string
: 오류 메시지에 특정 부분 문자열이 포함되는지 확인합니다.Error
,AsymmetricMatcher
:toEqual(received)
와 유사하게 예상된 객체와 비교합니다.
TIP
코드를 함수로 래핑해야 합니다. 그렇지 않으면 오류가 포착되지 않아 테스트가 실패합니다.
이는 rejects가 Promise를 올바르게 언래핑하므로 비동기 호출에는 적용되지 않습니다.
test('expect rejects toThrow', async ({ expect }) => {
const promise = Promise.reject(new Error('Test'));
await expect(promise).rejects.toThrowError();
});
예를 들어, getFruitStock('pineapples')
가 예외를 던지는지 테스트하려면 다음과 같이 작성할 수 있습니다.
import { expect, test } from 'vitest';
function getFruitStock(type: string) {
if (type === 'pineapples') {
throw new Error('Pineapples are not in stock');
}
// 다른 작업 수행
}
test('throws on pineapples', () => {
// 오류 메시지에 "stock"이 어딘가에 포함되어 있는지 테스트: 다음은 동일합니다.
expect(() => getFruitStock('pineapples')).toThrowError(/stock/);
expect(() => getFruitStock('pineapples')).toThrowError('stock');
// 정확한 오류 메시지 테스트
expect(() => getFruitStock('pineapples')).toThrowError(
/^Pineapples are not in stock$/
);
expect(() => getFruitStock('pineapples')).toThrowError(
new Error('Pineapples are not in stock')
);
expect(() => getFruitStock('pineapples')).toThrowError(
expect.objectContaining({
message: 'Pineapples are not in stock',
})
);
});
TIP
비동기 함수를 테스트하려면 rejects와 함께 사용하십시오.
function getAsyncFruitStock() {
return Promise.reject(new Error('empty'));
}
test('throws on pineapples', async () => {
await expect(() => getAsyncFruitStock()).rejects.toThrowError('empty');
});
toMatchSnapshot
- 타입:
<T>(shape?: Partial<T> | string, hint?: string) => void
이 메서드는 값이 가장 최근 스냅샷과 일치하는지 확인합니다.
선택적 hint
문자열 인수를 제공할 수 있으며, 이는 스냅샷 이름에 추가됩니다. Vitest는 항상 스냅샷 이름 끝에 숫자를 추가하지만, 짧고 설명적인 힌트가 단일 it
또는 test
블록에서 여러 스냅샷을 구별하는 데 숫자보다 더 유용할 수 있습니다. Vitest는 해당 .snap
파일에서 스냅샷을 이름순으로 정렬합니다.
TIP
스냅샷이 불일치하여 테스트가 실패하는 경우, 해당 불일치가 예상된 것이라면 u
키를 눌러 스냅샷을 한 번 업데이트할 수 있습니다. 또는 -u
또는 --update
CLI 옵션을 전달하여 Vitest가 항상 테스트를 업데이트하도록 할 수 있습니다.
import { expect, test } from 'vitest';
test('matches snapshot', () => {
const data = { foo: new Set(['bar', 'snapshot']) };
expect(data).toMatchSnapshot();
});
객체의 모양만 테스트하고 100% 호환될 필요가 없는 경우 객체의 모양을 제공할 수도 있습니다.
import { expect, test } from 'vitest';
test('matches snapshot', () => {
const data = { foo: new Set(['bar', 'snapshot']) };
expect(data).toMatchSnapshot({ foo: expect.any(Set) });
});
toMatchInlineSnapshot
- 타입:
<T>(shape?: Partial<T> | string, snapshot?: string, hint?: string) => void
이 메서드는 값이 가장 최근 스냅샷과 일치하는지 확인합니다.
Vitest는 외부 .snap
파일 대신 테스트 파일 내의 매처에 inlineSnapshot 문자열 인수를 추가하고 업데이트합니다.
import { expect, test } from 'vitest';
test('matches inline snapshot', () => {
const data = { foo: new Set(['bar', 'snapshot']) };
// Vitest는 스냅샷을 업데이트할 때 다음 내용을 업데이트합니다.
expect(data).toMatchInlineSnapshot(`
{
"foo": Set {
"bar",
"snapshot",
},
}
`);
});
객체의 모양만 테스트하고 100% 호환될 필요가 없는 경우 객체의 모양을 제공할 수도 있습니다.
import { expect, test } from 'vitest';
test('matches snapshot', () => {
const data = { foo: new Set(['bar', 'snapshot']) };
expect(data).toMatchInlineSnapshot(
{ foo: expect.any(Set) },
`
{
"foo": Any<Set>,
}
`
);
});
toMatchFileSnapshot
- 타입:
<T>(filepath: string, hint?: string) => Promise<void>
명시적으로 지정된 파일의 내용과 스냅샷을 비교하거나 업데이트합니다( .snap
파일 대신).
import { expect, it } from 'vitest';
it('render basic', async () => {
const result = renderHTML(h('div', { class: 'foo' }));
await expect(result).toMatchFileSnapshot('./test/basic.output.html');
});
파일 시스템 작업은 비동기적이므로 toMatchFileSnapshot()
과 함께 await
를 사용해야 합니다. await
를 사용하지 않으면 Vitest는 이를 expect.soft
처럼 처리합니다. 즉, 스냅샷이 불일치하더라도 해당 구문 뒤의 코드가 계속 실행됩니다. 테스트가 완료되면 Vitest는 스냅샷을 확인하고 불일치가 있으면 실패합니다.
toThrowErrorMatchingSnapshot
- 타입:
(hint?: string) => void
toMatchSnapshot
과 동일하지만 toThrowError
와 동일한 값을 예상합니다.
toThrowErrorMatchingInlineSnapshot
- 타입:
(snapshot?: string, hint?: string) => void
toMatchInlineSnapshot
과 동일하지만 toThrowError
와 동일한 값을 예상합니다.
toHaveBeenCalled
- 타입:
() => Awaitable<void>
이 단언은 함수가 호출되었는지 테스트할 때 유용합니다. expect
에 스파이 함수를 전달해야 합니다.
import { expect, test, vi } from 'vitest';
const market = {
buy(subject: string, amount: number) {
// ...
},
};
test('spy function', () => {
const buySpy = vi.spyOn(market, 'buy');
expect(buySpy).not.toHaveBeenCalled();
market.buy('apples', 10);
expect(buySpy).toHaveBeenCalled();
});
toHaveBeenCalledTimes
- 타입:
(amount: number) => Awaitable<void>
이 단언은 함수가 특정 횟수만큼 호출되었는지 확인합니다. expect
에 스파이 함수를 전달해야 합니다.
import { expect, test, vi } from 'vitest';
const market = {
buy(subject: string, amount: number) {
// ...
},
};
test('spy function called two times', () => {
const buySpy = vi.spyOn(market, 'buy');
market.buy('apples', 10);
market.buy('apples', 20);
expect(buySpy).toHaveBeenCalledTimes(2);
});
toHaveBeenCalledWith
- 타입:
(...args: any[]) => Awaitable<void>
이 단언은 함수가 특정 매개변수로 한 번 이상 호출되었는지 확인합니다. expect
에 스파이 함수를 전달해야 합니다.
import { expect, test, vi } from 'vitest';
const market = {
buy(subject: string, amount: number) {
// ...
},
};
test('spy function', () => {
const buySpy = vi.spyOn(market, 'buy');
market.buy('apples', 10);
market.buy('apples', 20);
expect(buySpy).toHaveBeenCalledWith('apples', 10);
expect(buySpy).toHaveBeenCalledWith('apples', 20);
});
toHaveBeenCalledBefore 3.0.0+
- 타입:
(mock: MockInstance, failIfNoFirstInvocation?: boolean) => Awaitable<void>
이 단언은 한 Mock
가 다른 Mock
보다 먼저 호출되었는지 확인합니다.
test('calls mock1 before mock2', () => {
const mock1 = vi.fn();
const mock2 = vi.fn();
mock1();
mock2();
mock1();
expect(mock1).toHaveBeenCalledBefore(mock2);
});
toHaveBeenCalledAfter 3.0.0+
- 타입:
(mock: MockInstance, failIfNoFirstInvocation?: boolean) => Awaitable<void>
이 단언은 한 Mock
가 다른 Mock
보다 나중에 호출되었는지 확인합니다.
test('calls mock1 after mock2', () => {
const mock1 = vi.fn();
const mock2 = vi.fn();
mock2();
mock1();
mock2();
expect(mock1).toHaveBeenCalledAfter(mock2);
});
toHaveBeenCalledExactlyOnceWith 3.0.0+
- 타입:
(...args: any[]) => Awaitable<void>
이 단언은 함수가 정확히 한 번, 그리고 특정 매개변수로 호출되었는지 확인합니다. expect
에 스파이 함수를 전달해야 합니다.
import { expect, test, vi } from 'vitest';
const market = {
buy(subject: string, amount: number) {
// ...
},
};
test('spy function', () => {
const buySpy = vi.spyOn(market, 'buy');
market.buy('apples', 10);
expect(buySpy).toHaveBeenCalledExactlyOnceWith('apples', 10);
});
toHaveBeenLastCalledWith
- 타입:
(...args: any[]) => Awaitable<void>
이 단언은 함수가 마지막 호출 시 특정 매개변수로 호출되었는지 확인합니다. expect
에 스파이 함수를 전달해야 합니다.
import { expect, test, vi } from 'vitest';
const market = {
buy(subject: string, amount: number) {
// ...
},
};
test('spy function', () => {
const buySpy = vi.spyOn(market, 'buy');
market.buy('apples', 10);
market.buy('apples', 20);
expect(buySpy).not.toHaveBeenLastCalledWith('apples', 10);
expect(buySpy).toHaveBeenLastCalledWith('apples', 20);
});
toHaveBeenNthCalledWith
- 타입:
(time: number, ...args: any[]) => Awaitable<void>
이 단언은 함수가 특정 순서(N번째)로 특정 매개변수와 함께 호출되었는지 확인합니다. 카운트는 1부터 시작합니다. 따라서 두 번째 호출을 확인하려면 .toHaveBeenNthCalledWith(2, ...)
와 같이 작성합니다.
expect
에 스파이 함수를 전달해야 합니다.
import { expect, test, vi } from 'vitest';
const market = {
buy(subject: string, amount: number) {
// ...
},
};
test('first call of spy function called with right params', () => {
const buySpy = vi.spyOn(market, 'buy');
market.buy('apples', 10);
market.buy('apples', 20);
expect(buySpy).toHaveBeenNthCalledWith(1, 'apples', 10);
});
toHaveReturned
- 타입:
() => Awaitable<void>
이 단언은 함수가 한 번 이상 성공적으로 값을 반환했는지(즉, 오류를 발생시키지 않았는지) 확인합니다. expect
에 스파이 함수를 전달해야 합니다.
import { expect, test, vi } from 'vitest';
function getApplesPrice(amount: number) {
const PRICE = 10;
return amount * PRICE;
}
test('spy function returned a value', () => {
const getPriceSpy = vi.fn(getApplesPrice);
const price = getPriceSpy(10);
expect(price).toBe(100);
expect(getPriceSpy).toHaveReturned();
});
toHaveReturnedTimes
- 타입:
(amount: number) => Awaitable<void>
이 단언은 함수가 정확히 특정 횟수만큼 성공적으로 값을 반환했는지(즉, 오류를 발생시키지 않았는지) 확인합니다. expect
에 스파이 함수를 전달해야 합니다.
import { expect, test, vi } from 'vitest';
test('spy function returns a value two times', () => {
const sell = vi.fn((product: string) => ({ product }));
sell('apples');
sell('bananas');
expect(sell).toHaveReturnedTimes(2);
});
toHaveReturnedWith
- 타입:
(returnValue: any) => Awaitable<void>
이 단언을 호출하여 함수가 특정 값을 가지고 한 번 이상 성공적으로 반환되었는지 확인할 수 있습니다. expect
에 스파이 함수를 전달해야 합니다.
import { expect, test, vi } from 'vitest';
test('spy function returns a product', () => {
const sell = vi.fn((product: string) => ({ product }));
sell('apples');
expect(sell).toHaveReturnedWith({ product: 'apples' });
});
toHaveLastReturnedWith
- 타입:
(returnValue: any) => Awaitable<void>
이 단언을 호출하여 함수가 마지막으로 호출되었을 때 특정 값을 성공적으로 반환했는지 확인할 수 있습니다. expect
에 스파이 함수를 전달해야 합니다.
import { expect, test, vi } from 'vitest';
test('spy function returns bananas on a last call', () => {
const sell = vi.fn((product: string) => ({ product }));
sell('apples');
sell('bananas');
expect(sell).toHaveLastReturnedWith({ product: 'bananas' });
});
toHaveNthReturnedWith
- 타입:
(time: number, returnValue: any) => Awaitable<void>
이 단언을 호출하여 함수가 특정 호출에서 특정 값을 성공적으로 반환했는지 확인할 수 있습니다. expect
에 스파이 함수를 전달해야 합니다.
import { expect, test, vi } from 'vitest';
test('spy function returns bananas on second call', () => {
const sell = vi.fn((product: string) => ({ product }));
sell('apples');
sell('bananas');
expect(sell).toHaveNthReturnedWith(2, { product: 'bananas' });
});
toHaveResolved
- 타입:
() => Awaitable<void>
이 단언은 함수가 한 번 이상 값을 성공적으로 해결했는지(즉, 거부되지 않았는지) 확인합니다. expect
에 스파이 함수를 전달해야 합니다.
함수가 Promise를 반환했지만 아직 해결되지 않은 경우 이 단언은 실패합니다.
import { expect, test, vi } from 'vitest';
import db from './db/apples.js';
async function getApplesPrice(amount: number) {
return amount * (await db.get('price'));
}
test('spy function resolved a value', async () => {
const getPriceSpy = vi.fn(getApplesPrice);
const price = await getPriceSpy(10);
expect(price).toBe(100);
expect(getPriceSpy).toHaveResolved();
});
toHaveResolvedTimes
- 타입:
(amount: number) => Awaitable<void>
이 단언은 함수가 정확히 특정 횟수만큼 값을 성공적으로 해결했는지(즉, 거부되지 않았는지) 확인합니다. expect
에 스파이 함수를 전달해야 합니다.
이것은 해결된 Promise만 계산합니다. 함수가 Promise를 반환했지만 아직 해결되지 않은 경우 계산되지 않습니다.
import { expect, test, vi } from 'vitest';
test('spy function resolved a value two times', async () => {
const sell = vi.fn((product: string) => Promise.resolve({ product }));
await sell('apples');
await sell('bananas');
expect(sell).toHaveResolvedTimes(2);
});
toHaveResolvedWith
- 타입:
(returnValue: any) => Awaitable<void>
이 단언을 호출하여 함수가 한 번 이상 특정 값을 성공적으로 해결했는지 확인할 수 있습니다. expect
에 스파이 함수를 전달해야 합니다.
함수가 Promise를 반환했지만 아직 해결되지 않은 경우 이 단언은 실패합니다.
import { expect, test, vi } from 'vitest';
test('spy function resolved a product', async () => {
const sell = vi.fn((product: string) => Promise.resolve({ product }));
await sell('apples');
expect(sell).toHaveResolvedWith({ product: 'apples' });
});
toHaveLastResolvedWith
- 타입:
(returnValue: any) => Awaitable<void>
이 단언을 호출하여 함수가 마지막으로 호출되었을 때 특정 값을 성공적으로 해결했는지 확인할 수 있습니다. expect
에 스파이 함수를 전달해야 합니다.
함수가 Promise를 반환했지만 아직 해결되지 않은 경우 이 단언은 실패합니다.
import { expect, test, vi } from 'vitest';
test('spy function resolves bananas on a last call', async () => {
const sell = vi.fn((product: string) => Promise.resolve({ product }));
await sell('apples');
await sell('bananas');
expect(sell).toHaveLastResolvedWith({ product: 'bananas' });
});
toHaveNthResolvedWith
- 타입:
(time: number, returnValue: any) => Awaitable<void>
이 단언을 호출하여 함수가 특정 호출에서 특정 값을 성공적으로 해결했는지 확인할 수 있습니다. expect
에 스파이 함수를 전달해야 합니다.
함수가 Promise를 반환했지만 아직 해결되지 않은 경우 이 단언은 실패합니다.
import { expect, test, vi } from 'vitest';
test('spy function returns bananas on second call', async () => {
const sell = vi.fn((product: string) => Promise.resolve({ product }));
await sell('apples');
await sell('bananas');
expect(sell).toHaveNthResolvedWith(2, { product: 'bananas' });
});
toSatisfy
- 타입:
(predicate: (value: any) => boolean) => Awaitable<void>
이 단언은 값이 특정 조건(predicate)을 만족하는지 확인합니다.
import { describe, expect, it } from 'vitest';
const isOdd = (value: number) => value % 2 !== 0;
describe('toSatisfy()', () => {
it('pass with 0', () => {
expect(1).toSatisfy(isOdd);
});
it('pass with negation', () => {
expect(2).not.toSatisfy(isOdd);
});
});
resolves
- 타입:
Promisify<Assertions>
resolves
는 비동기 코드를 단언할 때 반복적인 작업을 줄이기 위해 사용됩니다. 보류 중인 Promise에서 값을 언래핑하고 일반적인 단언으로 값을 검증하는 데 사용합니다. Promise가 거부되면 단언이 실패합니다.
이 메서드는 동일한 Assertions
객체를 반환하지만, 이제 모든 매처는 Promise
를 반환하므로 await
해야 합니다. chai
단언과도 작동합니다.
예를 들어, API 호출을 수행하고 일부 데이터를 반환하는 함수가 있는 경우 이 코드를 사용하여 반환 값을 단언할 수 있습니다.
import { expect, test } from 'vitest';
async function buyApples() {
return fetch('/buy/apples').then(r => r.json());
}
test('buyApples returns new stock id', async () => {
// toEqual은 이제 Promise를 반환하므로 반드시 await해야 합니다.
await expect(buyApples()).resolves.toEqual({ id: 1 }); // jest API
await expect(buyApples()).resolves.to.equal({ id: 1 }); // chai API
});
WARNING
단언이 await
되지 않으면 항상 통과하는 거짓 양성(false-positive) 테스트가 됩니다. 단언이 실제로 호출되었는지 확인하려면 expect.assertions(number)
를 사용할 수 있습니다.
Vitest 3부터는 메서드가 await
되지 않으면 테스트 끝에 경고가 표시됩니다. Vitest 4에서는 단언이 await
되지 않으면 테스트가 "실패"로 표시됩니다.
rejects
- 타입:
Promisify<Assertions>
rejects
는 비동기 코드를 단언할 때 반복적인 작업을 줄이기 위해 사용됩니다. Promise가 거부된 이유를 언래핑하고 일반적인 단언으로 값을 검증하는 데 사용합니다. Promise가 성공적으로 해결되면 단언이 실패합니다.
이 메서드는 동일한 Assertions
객체를 반환하지만, 이제 모든 매처는 Promise
를 반환하므로 await
해야 합니다. chai
단언과도 작동합니다.
예를 들어, 함수를 호출할 때 실패하는 함수가 있는 경우 이 코드를 사용하여 이유를 단언할 수 있습니다.
import { expect, test } from 'vitest';
async function buyApples(id) {
if (!id) {
throw new Error('no id');
}
}
test('buyApples throws an error when no id provided', async () => {
// toThrow는 이제 Promise를 반환하므로 반드시 await해야 합니다.
await expect(buyApples()).rejects.toThrow('no id');
});
WARNING
단언이 await
되지 않으면 항상 통과하는 거짓 양성(false-positive) 테스트가 됩니다. 단언이 실제로 호출되었는지 확인하려면 expect.assertions(number)
를 사용할 수 있습니다.
Vitest 3부터는 메서드가 await
되지 않으면 테스트 끝에 경고가 표시됩니다. Vitest 4에서는 단언이 await
되지 않으면 테스트가 "실패"로 표시됩니다.
expect.assertions
- 타입:
(count: number) => void
테스트가 통과하거나 실패한 후 테스트 중에 특정 수의 단언이 호출되었는지 확인합니다. 이는 비동기 코드가 호출되었는지 확인할 때 유용합니다.
예를 들어, 두 개의 매처를 비동기적으로 호출하는 함수가 있는 경우 실제로 호출되었는지 단언할 수 있습니다.
import { expect, test } from 'vitest';
async function doAsync(...cbs) {
await Promise.all(cbs.map((cb, index) => cb({ index })));
}
test('all assertions are called', async () => {
expect.assertions(2);
function callback1(data) {
expect(data).toBeTruthy();
}
function callback2(data) {
expect(data).toBeTruthy();
}
await doAsync(callback1, callback2);
});
WARNING
비동기 동시 테스트에서 assertions
를 사용할 때는 올바른 테스트가 감지되도록 로컬 테스트 컨텍스트의 expect
를 사용해야 합니다.
expect.hasAssertions
- 타입:
() => void
테스트가 통과하거나 실패한 후 테스트 중에 하나 이상의 단언이 호출되었는지 확인합니다. 이는 비동기 코드가 호출되었는지 확인할 때 유용합니다.
예를 들어, 콜백을 호출하는 코드가 있는 경우 콜백 내에서 단언을 만들 수 있지만, 단언이 실제로 호출되었는지 확인하지 않으면 테스트는 항상 통과합니다.
import { expect, test } from 'vitest';
import { db } from './db.js';
const cbs = [];
function onSelect(cb) {
cbs.push(cb);
}
// db에서 선택한 후 모든 콜백을 호출합니다.
function select(id) {
return db.select({ id }).then(data => {
return Promise.all(cbs.map(cb => cb(data)));
});
}
test('callback was called', async () => {
expect.hasAssertions();
onSelect(data => {
// 선택 시 호출되어야 합니다.
expect(data).toBeTruthy();
});
// await하지 않으면 테스트가 실패합니다.
// expect.hasAssertions()가 없으면 테스트가 통과합니다.
await select(3);
});
expect.unreachable
- 타입:
(message?: string) => never
이 메서드는 특정 코드 라인에 도달해서는 안 된다고 단언하는 데 사용됩니다.
예를 들어, src
폴더가 없는 디렉토리를 수신하여 build()
가 오류를 던지는지 테스트하고 각 오류를 개별적으로 처리하려면 다음과 같이 할 수 있습니다.
import { expect, test } from 'vitest';
async function build(dir) {
if (dir.includes('no-src')) {
throw new Error(`${dir}/src does not exist`);
}
}
const errorDirs = [
'no-src-folder',
// ...
];
test.each(errorDirs)('build fails with "%s"', async dir => {
try {
await build(dir);
expect.unreachable('Should not pass build');
} catch (err: any) {
expect(err).toBeInstanceOf(Error);
expect(err.stack).toContain('build');
switch (dir) {
case 'no-src-folder':
expect(err.message).toBe(`${dir}/src does not exist`);
break;
default:
// 모든 오류 테스트를 소진하기 위해
expect.unreachable('All error test must be handled');
break;
}
}
});
expect.anything
- 타입:
() => any
이 비대칭 매처는 동등성 검사와 함께 사용될 때 항상 true
를 반환합니다. 속성이 존재하는지 확인할 때 유용합니다.
import { expect, test } from 'vitest';
test('object has "apples" key', () => {
expect({ apples: 22 }).toEqual({ apples: expect.anything() });
});
expect.any
- 타입:
(constructor: unknown) => any
이 비대칭 매처는 동등성 검사와 함께 사용될 때, 값이 지정된 생성자의 인스턴스인 경우에만 true
를 반환합니다. 값이 매번 생성되더라도 올바른 타입으로 존재하는지 확인할 때 유용합니다.
import { expect, test } from 'vitest';
import { generateId } from './generators.js';
test('"id" is a number', () => {
expect({ id: generateId() }).toEqual({ id: expect.any(Number) });
});
expect.closeTo
- 타입:
(expected: any, precision?: number) => any
expect.closeTo
는 객체 속성이나 배열 항목에서 부동 소수점 숫자를 비교할 때 유용합니다. 단일 숫자를 비교해야 하는 경우 대신 .toBeCloseTo
를 사용하십시오.
선택적 precision
인수는 소수점 뒤에 확인할 자릿수를 제한합니다. 기본값 2
의 경우 테스트 기준은 Math.abs(expected - received) < 0.005 (즉, 10 ** -2 / 2)
입니다.
예를 들어, 이 테스트는 5자리 정밀도로 통과합니다.
test('compare float in object properties', () => {
expect({
title: '0.1 + 0.2',
sum: 0.1 + 0.2,
}).toEqual({
title: '0.1 + 0.2',
sum: expect.closeTo(0.3, 5),
});
});
expect.arrayContaining
- 타입:
<T>(expected: T[]) => any
동등성 검사와 함께 사용될 때, 이 비대칭 매처는 값이 배열이고 지정된 항목을 포함하는 경우 true
를 반환합니다.
import { expect, test } from 'vitest';
test('basket includes fuji', () => {
const basket = {
varieties: ['Empire', 'Fuji', 'Gala'],
count: 3,
};
expect(basket).toEqual({
count: 3,
varieties: expect.arrayContaining(['Fuji']),
});
});
TIP
이 매처와 함께 expect.not
을 사용하여 예상 값을 부정할 수 있습니다.
expect.objectContaining
- 타입:
(expected: any) => any
동등성 검사와 함께 사용될 때, 이 비대칭 매처는 값이 예상된 객체와 유사한 구조를 가지면 true
를 반환합니다.
import { expect, test } from 'vitest';
test('basket has empire apples', () => {
const basket = {
varieties: [
{
name: 'Empire',
count: 1,
},
],
};
expect(basket).toEqual({
varieties: [expect.objectContaining({ name: 'Empire' })],
});
});
TIP
이 매처와 함께 expect.not
을 사용하여 예상 값을 부정할 수 있습니다.
expect.stringContaining
- 타입:
(expected: any) => any
동등성 검사와 함께 사용될 때, 이 비대칭 매처는 값이 문자열이고 지정된 부분 문자열을 포함하는 경우 true
를 반환합니다.
import { expect, test } from 'vitest';
test('variety has "Emp" in its name', () => {
const variety = {
name: 'Empire',
count: 1,
};
expect(variety).toEqual({
name: expect.stringContaining('Emp'),
count: 1,
});
});
TIP
이 매처와 함께 expect.not
을 사용하여 예상 값을 부정할 수 있습니다.
expect.stringMatching
- 타입:
(expected: any) => any
동등성 검사와 함께 사용될 때, 이 비대칭 매처는 값이 문자열이고 지정된 부분 문자열을 포함하거나 정규 표현식과 일치하면 true
를 반환합니다.
import { expect, test } from 'vitest';
test('variety ends with "re"', () => {
const variety = {
name: 'Empire',
count: 1,
};
expect(variety).toEqual({
name: expect.stringMatching(/re$/),
count: 1,
});
});
TIP
이 매처와 함께 expect.not
을 사용하여 예상 값을 부정할 수 있습니다.
expect.addSnapshotSerializer
- 타입:
(plugin: PrettyFormatPlugin) => void
이 메서드는 스냅샷을 생성할 때 호출되는 사용자 정의 직렬 변환기를 추가합니다. 이는 고급 기능이므로, 더 자세히 알고 싶다면 사용자 정의 직렬 변환기 가이드를 참조하십시오.
사용자 정의 직렬 변환기를 추가하는 경우 setupFiles
내에서 이 메서드를 호출해야 합니다. 이는 모든 스냅샷에 적용됩니다.
TIP
이전에 Jest와 함께 Vue CLI를 사용했다면 jest-serializer-vue를 설치하는 것이 좋습니다. 그렇지 않으면 스냅샷이 문자열로 래핑되어 "
가 이스케이프됩니다.
expect.extend
- 타입:
(matchers: MatchersObject) => void
기본 매처를 사용자 정의 매처로 확장할 수 있습니다. 이 함수는 사용자 정의 매처로 매처 객체를 확장하는 데 사용됩니다.
이러한 방식으로 매처를 정의하면 expect.stringContaining
과 같이 사용할 수 있는 비대칭 매처도 생성됩니다.
import { expect, test } from 'vitest';
test('custom matchers', () => {
expect.extend({
toBeFoo: (received, expected) => {
if (received !== 'foo') {
return {
message: () => `expected ${received} to be foo`,
pass: false,
};
}
},
});
expect('foo').toBeFoo();
expect({ foo: 'foo' }).toEqual({ foo: expect.toBeFoo() });
});
TIP
매처가 모든 테스트에 나타나도록 하려면 setupFiles
내에서 이 메서드를 호출해야 합니다.
이 함수는 Jest의 expect.extend
와 호환되므로, 이를 사용하여 사용자 정의 매처를 생성하는 모든 라이브러리는 Vitest와 함께 작동합니다.
TypeScript를 사용하는 경우, Vitest 0.31.0부터는 아래 코드와 같이 앰비언트 선언 파일(예: vitest.d.ts
)을 통해 기본 Assertion
인터페이스를 확장할 수 있습니다.
interface CustomMatchers<R = unknown> {
toBeFoo: () => R;
}
declare module 'vitest' {
interface Assertion<T = any> extends CustomMatchers<T> {}
interface AsymmetricMatchersContaining extends CustomMatchers {}
}
WARNING
앰비언트 선언 파일을 tsconfig.json
에 포함하는 것을 잊지 마세요.
TIP
더 자세히 알고 싶다면 매처 확장 가이드를 확인하십시오.
expect.addEqualityTesters
- 타입:
(tester: Array<Tester>) => void
이 메서드를 사용하여 사용자 정의 테스터를 정의할 수 있습니다. 테스터는 두 객체가 같은지 테스트하기 위해 매처가 사용하는 메서드이며, Jest의 expect.addEqualityTesters
와 호환됩니다.
import { expect, test } from 'vitest';
class AnagramComparator {
public word: string;
constructor(word: string) {
this.word = word;
}
equals(other: AnagramComparator): boolean {
const cleanStr1 = this.word.replace(/ /g, '').toLowerCase();
const cleanStr2 = other.word.replace(/ /g, '').toLowerCase();
const sortedStr1 = cleanStr1.split('').sort().join('');
const sortedStr2 = cleanStr2.split('').sort().join('');
return sortedStr1 === sortedStr2;
}
}
function isAnagramComparator(a: unknown): a is AnagramComparator {
return a instanceof AnagramComparator;
}
function areAnagramsEqual(a: unknown, b: unknown): boolean | undefined {
const isAAnagramComparator = isAnagramComparator(a);
const isBAnagramComparator = isAnagramComparator(b);
if (isAAnagramComparator && isBAnagramComparator) {
return a.equals(b);
} else if (isAAnagramComparator === isBAnagramComparator) {
return undefined;
} else {
return false;
}
}
expect.addEqualityTesters([areAnagramsEqual]);
test('custom equality tester', () => {
expect(new AnagramComparator('listen')).toEqual(
new AnagramComparator('silent')
);
});