expect
Az alábbi típusok használatosak az alábbi típusdefiníciókban:
type Awaitable<T> = T | PromiseLike<T>;
Az expect
állítások létrehozására szolgál. Ebben a kontextusban az állítások olyan függvények, amelyekkel ellenőrizhető egy feltétel helyessége. A Vitest alapértelmezés szerint chai
állításokat biztosít, valamint Jest
kompatibilis állításokat, amelyek a chai
-ra épülnek.
Például ez a kód azt állítja, hogy egy input
érték egyenlő 2
-vel. Ha ez nem igaz, az állítás hibát dob, és a teszt sikertelen lesz.
import { expect } from 'vitest';
const input = Math.sqrt(4);
expect(input).to.equal(2); // chai API
expect(input).toBe(2); // jest API
Technikai szempontból ez a példa nem használja a test
függvényt, ezért a konzolon a Vitest kimenete helyett Node.js hibát fog látni. Ha többet szeretne megtudni a test
-ről, olvassa el a Teszt API Referenciát.
Továbbá, az expect
statikusan is használható a későbbiekben ismertetett egyeztető függvények eléréséhez, és még sok másra.
WARNING
Az expect
nem befolyásolja a típusok tesztelését, ha a kifejezésben nincs típushiba. Ha a Vitest-et típusellenőrzőként szeretné használni, használja az expectTypeOf
vagy az assertType
függvényeket.
soft
- Típus:
ExpectStatic & (actual: any) => Assertions
Az expect.soft
hasonlóan működik, mint az expect
, azzal a különbséggel, hogy sikertelen állítás esetén nem szakítja meg a teszt futását, hanem teszthibaként jelöli azt. A teszt során előforduló összes hiba a teszt befejezésekor jelenik meg.
import { expect, test } from 'vitest';
test('expect.soft teszt', () => {
expect.soft(1 + 1).toBe(3); // sikertelenként jelöli meg a tesztet és folytatja
expect.soft(1 + 2).toBe(4); // sikertelenként jelöli meg a tesztet és folytatja
});
// A teszt végén a fenti hibák kiírásra kerülnek.
Használható az expect
-tel is. Ha az expect
állítás meghiúsul, a teszt megszakad, és az összes hiba megjelenik.
import { expect, test } from 'vitest';
test('expect.soft teszt', () => {
expect.soft(1 + 1).toBe(3); // sikertelenként jelöli meg a tesztet és folytatja
expect(1 + 2).toBe(3); // sikeres, de megszakítja a tesztet, az összes korábbi hiba kiírásra kerül
expect.soft(1 + 2).toBe(4); // nem fut le
});
WARNING
Az expect.soft
csak a test
függvényen belül használható.
not
A not
használata negálja az állítást. Például ez a kód azt állítja, hogy egy input
érték nem egyenlő 2
-vel. Ha egyenlő, az állítás hibát dob, és a teszt sikertelen lesz.
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
- Típus:
(value: any) => Awaitable<void>
A toBe
használható annak ellenőrzésére, hogy primitív értékek egyenlőek-e, vagy objektumok ugyanarra a memóriaterületre mutatnak-e. Egyenértékű az expect(Object.is(3, 3)).toBe(true)
hívással. Ha az objektumok nem azonosak, de ellenőrizni szeretné, hogy a struktúrájuk azonos-e, használhatja a toEqual
függvényt.
Például az alábbi kód ellenőrzi, hogy a kereskedőnek 13 almája van-e.
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; // ugyanaz a referencia
expect(stock).toBe(refStock);
});
Próbálja meg ne használni a toBe
függvényt lebegőpontos számokkal. Mivel a JavaScript kerekíti őket, a 0.1 + 0.2
nem szigorúan 0.3
. A lebegőpontos számok megbízható ellenőrzéséhez használja a toBeCloseTo
állítást.
toBeCloseTo
- Típus:
(value: number, numDigits?: number) => Awaitable<void>
Használja a toBeCloseTo
függvényt a lebegőpontos számok összehasonlításához. Az opcionális numDigits
argumentum a tizedesvessző után ellenőrzött számjegyek számát határozza meg. Például:
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 az 0.30000000000000004
});
test('decimals are rounded to 5 after the point', () => {
// 0.2 + 0.1 az 0.30000 | "000000000004" eltávolítva
expect(0.2 + 0.1).toBeCloseTo(0.3, 5);
// semmi sem lett eltávolítva a 0.30000000000000004-ből
expect(0.2 + 0.1).not.toBeCloseTo(0.3, 50);
});
toBeDefined
- Típus:
() => Awaitable<void>
A toBeDefined
azt állítja, hogy az érték nem undefined
. Hasznos lehet annak ellenőrzésére, hogy egy függvény adott-e vissza értéket.
import { expect, test } from 'vitest';
function getApples() {
return 3;
}
test('function returned something', () => {
expect(getApples()).toBeDefined();
});
toBeUndefined
- Típus:
() => Awaitable<void>
A toBeDefined
ellentéte, a toBeUndefined
azt állítja, hogy az érték undefined
. Hasznos lehet annak ellenőrzésére, hogy egy függvény nem adott vissza semmit.
import { expect, test } from 'vitest';
function getApplesFromStock(stock) {
if (stock === 'Bill') return 13;
}
test("mary doesn't have a stock", () => {
expect(getApplesFromStock('Mary')).toBeUndefined();
});
toBeTruthy
- Típus:
() => Awaitable<void>
A toBeTruthy
azt állítja, hogy az érték igaz, amikor logikai értékké konvertálják. Hasznos, ha nem érdekli az érték, csak azt szeretné tudni, hogy true
-ra konvertálható-e.
Például, ha ez a kód van, nem érdekli a stocks.getInfo
visszatérési értéke - lehet egy összetett objektum, egy string vagy bármi más. A kód továbbra is működni fog.
import { Stocks } from './stocks.js';
const stocks = new Stocks();
stocks.sync('Bill');
if (stocks.getInfo('Bill')) stocks.sell('apples', 'Bill');
Tehát, ha azt szeretné tesztelni, hogy a stocks.getInfo
igaz értéket ad-e vissza, akkor ezt írhatja:
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();
});
A JavaScriptben minden érték igaz, kivéve a false
, 0
, ''
, null
, undefined
és NaN
értékeket.
toBeFalsy
- Típus:
() => Awaitable<void>
A toBeFalsy
azt állítja, hogy az érték hamis, amikor logikai értékké konvertálják. Hasznos, ha nem érdekli az érték, csak azt szeretné tudni, hogy false
-ra konvertálható-e.
Például, ha ez a kód van, nem érdekli a stocks.stockFailed
visszatérési értéke - bármilyen hamis értéket visszaadhat, de a kód továbbra is működni fog.
import { Stocks } from './stocks.js';
const stocks = new Stocks();
stocks.sync('Bill');
if (!stocks.stockFailed('Bill')) stocks.sell('apples', 'Bill');
Tehát, ha azt szeretné tesztelni, hogy a stocks.stockFailed
hamis értéket ad-e vissza, akkor ezt írhatja:
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();
});
A JavaScriptben minden érték igaz, kivéve a false
, 0
, ''
, null
, undefined
és NaN
értékeket.
toBeNull
- Típus:
() => Awaitable<void>
A toBeNull
egyszerűen azt állítja, hogy valami null
-e. Ugyanaz, mint a .toBe(null)
.
import { expect, test } from 'vitest';
function apples() {
return null;
}
test("we don't have apples", () => {
expect(apples()).toBeNull();
});
toBeNaN
- Típus:
() => Awaitable<void>
A toBeNaN
egyszerűen azt állítja, hogy valami NaN
-e. Ugyanaz, mint a .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();
});
toBeTypeOf
- Típus:
(c: 'bigint' | 'boolean' | 'function' | 'number' | 'object' | 'string' | 'symbol' | 'undefined') => Awaitable<void>
A toBeTypeOf
azt állítja, hogy egy tényleges érték a megadott típusú-e.
import { expect, test } from 'vitest';
const actual = 'stock';
test('stock is type of string', () => {
expect(actual).toBeTypeOf('string');
});
toBeInstanceOf
- Típus:
(c: any) => Awaitable<void>
A toBeInstanceOf
azt állítja, hogy egy tényleges érték a kapott osztály példánya-e.
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
- Típus:
(n: number | bigint) => Awaitable<void>
A toBeGreaterThan
azt állítja, hogy a tényleges érték nagyobb, mint a megadott érték. Az egyenlő értékek sikertelen tesztet eredményeznek.
import { expect, test } from 'vitest';
import { getApples } from './stocks.js';
test('have more then 10 apples', () => {
expect(getApples()).toBeGreaterThan(10);
});
toBeGreaterThanOrEqual
- Típus:
(n: number | bigint) => Awaitable<void>
A toBeGreaterThanOrEqual
azt állítja, hogy a tényleges érték nagyobb, mint a kapott érték, vagy egyenlő vele.
import { expect, test } from 'vitest';
import { getApples } from './stocks.js';
test('have 11 apples or more', () => {
expect(getApples()).toBeGreaterThanOrEqual(11);
});
toBeLessThan
- Típus:
(n: number | bigint) => Awaitable<void>
A toBeLessThan
azt állítja, hogy a tényleges érték kisebb, mint a megadott érték. Az egyenlő értékek sikertelen tesztet eredményeznek.
import { expect, test } from 'vitest';
import { getApples } from './stocks.js';
test('have less then 20 apples', () => {
expect(getApples()).toBeLessThan(20);
});
toBeLessThanOrEqual
- Típus:
(n: number | bigint) => Awaitable<void>
A toBeLessThanOrEqual
azt állítja, hogy a tényleges érték kisebb, mint a kapott érték, vagy egyenlő vele.
import { expect, test } from 'vitest';
import { getApples } from './stocks.js';
test('have 11 apples or less', () => {
expect(getApples()).toBeLessThanOrEqual(11);
});
toEqual
- Típus:
(received: any) => Awaitable<void>
A toEqual
azt állítja, hogy a tényleges érték megegyezik a várt értékkel, vagy objektumok esetén azonos a struktúrájuk (rekurzív összehasonlítással). A toEqual
és a toBe
közötti különbséget ebben a példában láthatja:
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
A mély egyenlőség nem kerül végrehajtásra az Error
objektumok esetében. Annak teszteléséhez, hogy valami kivételt dobott-e, használja a toThrowError
állítást.
toStrictEqual
- Típus:
(received: any) => Awaitable<void>
A toStrictEqual
azt állítja, hogy a tényleges érték egyenlő a kapott értékkel, vagy ugyanazzal a struktúrával rendelkezik, ha objektum (rekurzívan hasonlítja össze őket), és ugyanazon típusú.
Különbségek a .toEqual
-től:
- Az
undefined
tulajdonságokkal rendelkező kulcsok ellenőrzésre kerülnek. pl. a{a: undefined, b: 2}
nem egyezik a{b: 2}
-vel a.toStrictEqual
használatakor. - A tömb ritkasága ellenőrzésre kerül. pl. a
[, 1]
nem egyezik a[undefined, 1]
-vel a.toStrictEqual
használatakor. - Az objektumok típusát is ellenőrzi. Például egy
a
ésb
mezőkkel rendelkező osztálypéldány nem egyezik meg egya
ésb
mezőkkel rendelkező literális objektummal.
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
- Típus:
(received: string) => Awaitable<void>
A toContain
azt állítja, hogy a várt érték megtalálható egy tömbben. A toContain
azt is ellenőrizheti, hogy egy string egy másik string részstringje-e.
import { expect, test } from 'vitest';
import { getAllFruits } from './stocks.js';
test('the fruit list contains orange', () => {
expect(getAllFruits()).toContain('orange');
});
toContainEqual
- Típus:
(received: any) => Awaitable<void>
A toContainEqual
azt állítja, hogy egy adott struktúrával és értékekkel rendelkező elem szerepel egy tömbben. Minden elemre ugyanúgy működik, mint a toEqual
.
import { expect, test } from 'vitest';
import { getFruitStock } from './stocks.js';
test('apple available', () => {
expect(getFruitStock()).toContainEqual({ fruit: 'apple', count: 5 });
});
toHaveLength
- Típus:
(received: number) => Awaitable<void>
A toHaveLength
azt állítja, hogy egy objektumnak van .length
tulajdonsága, és egy bizonyos numerikus értékre van állítva.
import { expect, test } from 'vitest';
test('toHaveLength', () => {
expect('abc').toHaveLength(3);
expect([1, 2, 3]).toHaveLength(3);
expect('').not.toHaveLength(3); // nem 3 a .length tulajdonságának értéke
expect({ length: 3 }).toHaveLength(3);
});
toHaveProperty
Típus:
(key: any, received?: any) => Awaitable<void>
A
toHaveProperty
azt ellenőrzi, hogy a megadottkey
kulcs létezik-e egy objektumban, mint tulajdonság.Opcionálisan megadható egy érték argumentum is, amely mély összehasonlításként működik (hasonlóan a
toEqual
matcherhez), és a kapott tulajdonság értékét hasonlítja össze a megadott értékkel.tsimport { 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'); // annak ellenőrzése, hogy a kulcs létezik-e expect(invoice).toHaveProperty('total_amount', 5000); // annak ellenőrzése, hogy a kulcs létezik-e és az érték egyenlő expect(invoice).not.toHaveProperty('account'); // annak ellenőrzése, hogy ez a kulcs nem létezik // Mély hivatkozás pont operátorral expect(invoice).toHaveProperty('customer.first_name'); expect(invoice).toHaveProperty('customer.last_name', 'Doe'); expect(invoice).not.toHaveProperty('customer.location', 'India'); // Mély hivatkozás a kulcsokat tartalmazó tömb használatával expect(invoice).toHaveProperty('items[0].type', 'apples'); expect(invoice).toHaveProperty('items.0.type', 'apples'); // a pont jelölés is működik // Mély hivatkozás a keyPath-t tartalmazó tömb használatával expect(invoice).toHaveProperty(['items', 0, 'type'], 'apples'); expect(invoice).toHaveProperty(['items', '0', 'type'], 'apples'); // a szöveges jelölés is működik // Tegye a kulcsot egy tömbbe, hogy elkerülje, hogy a kulcsot mély hivatkozásként értelmezze a rendszer. expect(invoice).toHaveProperty(['P.O'], '12345'); });
toMatch
Típus:
(received: string | regexp) => Awaitable<void>
A
toMatch
azt ellenőrzi, hogy egy szöveg megfelel-e egy reguláris kifejezésnek vagy egy másik szövegnek.tsimport { expect, test } from 'vitest'; test('top fruits', () => { expect('top fruits include apple, orange and grape').toMatch(/apple/); expect('applefruits').toMatch('fruit'); // a `toMatch` szöveget is elfogad. });
TIP
Ha a hibaüzenetben szereplő érték túl rövidített, növelheti a chaiConfig.truncateThreshold értékét a konfigurációs fájlban.
toMatchObject
Típus:
(received: object | array) => Awaitable<void>
A
toMatchObject
azt ellenőrzi, hogy egy objektum megfelel-e egy másik objektum tulajdonságainak egy részhalmazának.Átadhat egy objektumokat tartalmazó tömböt is. Ez akkor hasznos, ha azt szeretné tesztelni, hogy két tömb elemeinek száma pontosan megegyezik-e, ellentétben az
arrayContaining
függvénnyel, ami megengedi a többlet elemeket a kapott tömbben.tsimport { 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', () => { // Annak ellenőrzése, hogy egy objektumokból álló tömb megfelel-e expect([{ foo: 'bar' }, { baz: 1 }]).toMatchObject([ { foo: 'bar' }, { baz: 1 }, ]); });
toThrowError
Típus:
(received: any) => Awaitable<void>
Alias:
toThrow
A
toThrowError
azt ellenőrzi, hogy egy függvény hibát dob-e, amikor meghívják.Megadható egy opcionális argumentum annak tesztelésére, hogy egy adott típusú hiba keletkezik-e:
- reguláris kifejezés: a hibaüzenet megfelel a mintának
- szöveg: a hibaüzenet tartalmazza a megadott szöveget
TIP
A kódot egy függvénybe kell csomagolni, különben a hiba nem lesz elkapva, és a teszt sikertelen lesz.
Például, ha azt szeretnénk tesztelni, hogy a
getFruitStock('pineapples')
hibát dob, akkor a következőképpen írhatjuk:tsimport { expect, test } from 'vitest'; function getFruitStock(type) { if (type === 'pineapples') throw new DiabetesError( 'Pineapples are not good for people with diabetes' ); // Do some other stuff } test('throws on pineapples', () => { // Annak tesztelése, hogy a hibaüzenet valahol azt mondja, hogy "diabetes": ezek egyenértékűek expect(() => getFruitStock('pineapples')).toThrowError(/diabetes/); expect(() => getFruitStock('pineapples')).toThrowError('diabetes'); // A pontos hibaüzenet tesztelése expect(() => getFruitStock('pineapples')).toThrowError( /^Pineapples are not good for people with diabetes$/ ); });
TIP
Aszinkron függvények teszteléséhez használja a rejects függvénnyel kombinálva.
jsfunction getAsyncFruitStock() { return Promise.reject(new Error('empty')); } test('throws on pineapples', async () => { await expect(() => getAsyncFruitStock()).rejects.toThrowError('empty'); });
toMatchSnapshot
Típus:
<T>(shape?: Partial<T> | string, message?: string) => void
Ez biztosítja, hogy egy érték megfeleljen a legutóbbi pillanatképnek.
Megadható egy opcionális
hint
szöveges argumentum, amely a teszt nevéhez lesz hozzáfűzve. Bár a Vitest mindig hozzáfűz egy számot a pillanatkép nevének végéhez, a rövid leíró megjegyzések hasznosabbak lehetnek, mint a számok, ha több pillanatképet szeretne megkülönböztetni egyetlenit
vagytest
blokkban. A Vitest a pillanatképeket név szerint rendezi a megfelelő.snap
fájlban.TIP
Ha a pillanatkép nem egyezik, és a teszt emiatt megbukik, az
u
gombot megnyomva egyszer frissítheti a pillanatképet. Alternatív megoldásként használhatja a-u
vagy--update
CLI opciókat, hogy a Vitest automatikusan frissítse a teszteket.tsimport { expect, test } from 'vitest'; test('matches snapshot', () => { const data = { foo: new Set(['bar', 'snapshot']) }; expect(data).toMatchSnapshot(); });
Megadhat egy objektum alakzatot is, ha csak egy objektum alakzatát teszteli, és nem szükséges a 100%-os kompatibilitás:
tsimport { expect, test } from 'vitest'; test('matches snapshot', () => { const data = { foo: new Set(['bar', 'snapshot']) }; expect(data).toMatchSnapshot({ foo: expect.any(Set) }); });
toMatchInlineSnapshot
Típus:
<T>(shape?: Partial<T> | string, snapshot?: string, message?: string) => void
Ez biztosítja, hogy egy érték megfeleljen a legutóbbi inline pillanatképnek.
A Vitest hozzáadja és frissíti az
inlineSnapshot
szöveges argumentumot a tesztfájlban lévő matcherhez (a külső.snap
fájl helyett).tsimport { expect, test } from 'vitest'; test('matches inline snapshot', () => { const data = { foo: new Set(['bar', 'snapshot']) }; // A Vitest frissíti a következő tartalmat a pillanatkép frissítésekor expect(data).toMatchInlineSnapshot(` { "foo": Set { "bar", "snapshot", }, } `); });
Megadhat egy objektum alakzatot is, ha csak egy objektum alakzatát teszteli, és nem szükséges a 100%-os kompatibilitás:
tsimport { 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ípus:
<T>(filepath: string, message?: string) => Promise<void>
Verzió: Vitest 0.30.0 óta
Összehasonlítja vagy frissíti a pillanatképet egy explicit módon megadott fájl tartalmával (a
.snap
fájl helyett).tsimport { expect, it } from 'vitest'; it('render basic', async () => { const result = renderHTML(h('div', { class: 'foo' })); await expect(result).toMatchFileSnapshot('./test/basic.output.html'); });
Fontos megjegyezni, hogy mivel a fájlrendszer művelet aszinkron, a
toMatchFileSnapshot()
használatakorawait
-et kell használnia.
toThrowErrorMatchingSnapshot
Típus:
(message?: string) => void
Ugyanaz, mint a
toMatchSnapshot
, de ugyanazt az értéket várja, mint atoThrowError
.Ha a függvény
Error
típust dob, a pillanatkép a hibaüzenet lesz. Ellenkező esetben a pillanatkép a függvény által dobott érték lesz.
toThrowErrorMatchingInlineSnapshot
Típus:
(snapshot?: string, message?: string) => void
Ugyanaz, mint a
toMatchInlineSnapshot
, de ugyanazt az értéket várja, mint atoThrowError
.Ha a függvény
Error
típust dob, a pillanatkép a hibaüzenet lesz. Ellenkező esetben a pillanatkép a függvény által dobott érték lesz.
toHaveBeenCalled
Típus:
() => Awaitable<void>
Ez az állítás hasznos annak tesztelésére, hogy egy függvényt meghívtak-e már. Ehhez egy megfigyelő (spy) függvényt kell átadni az
expect
-nek.tsimport { 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
- Típus:
(amount: number) => Awaitable<void>
Ez az állítás ellenőrzi, hogy egy függvényt hányszor hívtak meg. Ehhez egy megfigyelő (spy) függvényt kell átadni az expect
-nek.
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
- Típus:
(...args: any[]) => Awaitable<void>
Ez az állítás ellenőrzi, hogy egy függvényt legalább egyszer meghívtak-e a megadott paraméterekkel. Ehhez egy megfigyelő (spy) függvényt kell átadni az expect
-nek.
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);
});
toHaveBeenLastCalledWith
- Típus:
(...args: any[]) => Awaitable<void>
Ez az állítás ellenőrzi, hogy egy függvényt az utolsó meghívásakor a megadott paraméterekkel hívták-e meg. Ehhez egy megfigyelő (spy) függvényt kell átadni az expect
-nek.
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
- Típus:
(time: number, ...args: any[]) => Awaitable<void>
Ez az állítás ellenőrzi, hogy egy függvényt egy adott alkalommal a megadott paraméterekkel hívták-e meg. A számozás 1-től kezdődik. Tehát a második meghívás ellenőrzéséhez a következőt kell használni: .toHaveBeenNthCalledWith(2, ...)
.
Ehhez egy megfigyelő (spy) függvényt kell átadni az expect
-nek.
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
- Típus:
() => Awaitable<void>
Ez az állítás ellenőrzi, hogy egy függvény legalább egyszer sikeresen visszaadott-e egy értéket (azaz nem dobott-e hibát). Ehhez egy megfigyelő (spy) függvényt kell átadni az expect
-nek.
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
- Típus:
(amount: number) => Awaitable<void>
Ez az állítás ellenőrzi, hogy egy függvény pontosan hányszor adott vissza sikeresen egy értéket (azaz nem dobott-e hibát). Ehhez egy megfigyelő (spy) függvényt kell átadni az expect
-nek.
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
- Típus:
(returnValue: any) => Awaitable<void>
Ezzel az állítással ellenőrizheted, hogy egy függvény legalább egyszer sikeresen visszaadott-e egy bizonyos értéket. A teszteléshez egy megfigyelő (mock) függvényt kell átadnod az expect
függvénynek.
import { expect, test, vi } from 'vitest';
test('a megfigyelő függvény visszaad egy terméket', () => {
const sell = vi.fn((product: string) => ({ product }));
sell('apples');
expect(sell).toHaveReturnedWith({ product: 'apples' });
});
toHaveLastReturnedWith
- Típus:
(returnValue: any) => Awaitable<void>
Ezzel az állítással ellenőrizheted, hogy egy függvény az utolsó hívásakor sikeresen visszaadott-e egy bizonyos értéket. A teszteléshez egy megfigyelő (mock) függvényt kell átadnod az expect
függvénynek.
import { expect, test, vi } from 'vitest';
test('a megfigyelő függvény banánt ad vissza az utolsó híváskor', () => {
const sell = vi.fn((product: string) => ({ product }));
sell('apples');
sell('bananas');
expect(sell).toHaveLastReturnedWith({ product: 'bananas' });
});
toHaveNthReturnedWith
- Típus:
(time: number, returnValue: any) => Awaitable<void>
Ezzel az állítással ellenőrizheted, hogy egy függvény egy adott hívásakor sikeresen visszaadott-e egy bizonyos értéket. A teszteléshez egy megfigyelő (mock) függvényt kell átadnod az expect
függvénynek.
import { expect, test, vi } from 'vitest';
test('a megfigyelő függvény banánt ad vissza a második híváskor', () => {
const sell = vi.fn((product: string) => ({ product }));
sell('apples');
sell('bananas');
expect(sell).toHaveNthReturnedWith(2, { product: 'bananas' });
});
toSatisfy
- Típus:
(predicate: (value: any) => boolean) => Awaitable<void>
Ez az állítás ellenőrzi, hogy egy érték megfelel-e egy adott feltételnek (predikátumnak).
describe('toSatisfy()', () => {
const isOdd = (value: number) => value % 2 !== 0;
it('sikeres 1-gyel', () => {
expect(1).toSatisfy(isOdd);
});
it('sikeres negációval', () => {
expect(2).not.toSatisfy(isOdd);
});
});
resolves
Típus:
Promisify<Assertions>
A
resolves
célja a boilerplate kód csökkentése aszinkron kódok tesztelésekor. Segítségével hozzáférhetsz a promise által feloldott értékhez, és a szokásos módon tesztelheted azt. Ha a promise elutasításra kerül (reject), a teszt sikertelen lesz.Ugyanazt az
Assertions
objektumot adja vissza, de mostantól minden matcherPromise
-t ad vissza, ezértawait
-elni kell. Achai
állításokkal is működik.Például, ha van egy függvényed, amely API hívást kezdeményez és adatokat ad vissza, akkor az alábbi kóddal tesztelheted a visszatérési értékét:
tsimport { expect, test } from 'vitest'; async function buyApples() { return fetch('/buy/apples').then(r => r.json()); } test('buyApples új készletazonosítót ad vissza', async () => { // a `toEqual` most egy promise-t ad vissza, ezért KÖTELEZŐ `await`-elni await expect(buyApples()).resolves.toEqual({ id: 1 }); // jest API await expect(buyApples()).resolves.to.equal({ id: 1 }); // chai API });
WARNING
Ha az állítás nincs await-elve, akkor egy hamis-pozitív teszted lesz, ami minden alkalommal sikeres lesz. Annak biztosítására, hogy az állítások ténylegesen meghívásra kerüljenek, használhatod az
expect.assertions(number)
metódust.
rejects
Típus:
Promisify<Assertions>
A
rejects
célja a boilerplate kód csökkentése aszinkron kódok tesztelésekor. Segítségével hozzáférhetsz a promise elutasításának okához, és a szokásos módon tesztelheted azt. Ha a promise sikeresen feloldódik (resolve), a teszt sikertelen lesz.Ugyanazt az
Assertions
objektumot adja vissza, de mostantól minden matcherPromise
-t ad vissza, ezértawait
-elni kell. Achai
állításokkal is működik.Például, ha van egy függvényed, ami hibát dob, amikor meghívod, akkor az alábbi kóddal tesztelheted az okot:
tsimport { expect, test } from 'vitest'; async function buyApples(id) { if (!id) throw new Error('nincs azonosító'); } test('a buyApples hibát dob, ha nincs azonosító megadva', async () => { // a toThrow most egy promise-t ad vissza, ezért KÖTELEZŐ await-elni await expect(buyApples()).rejects.toThrow('nincs azonosító'); });
WARNING
Ha az állítás nincs await-elve, akkor egy hamis-pozitív teszted lesz, ami minden alkalommal sikeres lesz. Annak biztosítására, hogy az állítások ténylegesen meghívásra kerüljenek, használhatod az
expect.assertions(number)
metódust.
expect.assertions
Típus:
(count: number) => void
A teszt sikeres vagy sikertelen lefutása után ellenőrizheted, hogy egy adott számú állítás meghívásra került-e a teszt során. Ez hasznos lehet annak ellenőrzésére, hogy egy aszinkron kód meghívásra került-e.
Például, ha van egy függvényünk, ami aszinkron módon két matchert hív meg, akkor ellenőrizhetjük, hogy ténylegesen meghívásra kerültek-e.
tsimport { expect, test } from 'vitest'; async function doAsync(...cbs) { await Promise.all(cbs.map((cb, index) => cb({ index }))); } test('minden állítás meghívásra kerül', async () => { expect.assertions(2); function callback1(data) { expect(data).toBeTruthy(); } function callback2(data) { expect(data).toBeTruthy(); } await doAsync(callback1, callback2); });
WARNING
Ha az
assertions
-t aszinkron, párhuzamos tesztekkel használod, a helyi Teszt Konteksztből származóexpect
-et kell használni a megfelelő teszt észleléséhez.
expect.hasAssertions
Típus:
() => void
A teszt sikeres vagy sikertelen lefutása után ellenőrizheted, hogy legalább egy állítás meghívásra került-e a teszt során. Ez hasznos lehet annak ellenőrzésére, hogy egy aszinkron kód meghívásra került-e.
Például, ha van egy kódod, ami egy visszahívó függvényt hív meg, akkor tehetünk egy állítást a visszahívó függvényen belül, de a teszt mindig sikeres lesz, ha nem ellenőrizzük, hogy történt-e állítás.
tsimport { expect, test } from 'vitest'; import { db } from './db.js'; const cbs = []; function onSelect(cb) { cbs.push(cb); } // miután kiválasztottunk az adatbázisból, meghívjuk az összes visszahívó függvényt function select(id) { return db.select({ id }).then(data => { return Promise.all(cbs.map(cb => cb(data))); }); } test('a visszahívó függvény meghívásra került', async () => { expect.hasAssertions(); onSelect(data => { // a select függvény hívásakor kell meghívódnia expect(data).toBeTruthy(); }); // ha nincs await-elve, a teszt megbukik // ha nincs expect.hasAssertions(), a teszt sikeres lesz await select(3); });
expect.unreachable
Típus:
(message?: string) => never
Ezzel a metódussal azt állíthatjuk, hogy egy adott kódsor soha nem kerül végrehajtásra. Ha a kód mégis eléri ezt a pontot, a teszt megbukik.
Például, ha azt akarjuk tesztelni, hogy a
build()
hibát dob, mert a könyvtárakban nincssrc
mappa, és minden hibát külön kezelünk, akkor ezt tehetjük:tsimport { 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)('a build megbukik a "%s"-sel', async dir => { try { await build(dir); expect.unreachable('A build-nek nem szabadna sikerülnie'); } 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: // az összes hibateszt kimerítéséhez expect.unreachable('Minden hibateszt esetét kezelni kell'); break; } } });
expect.anything
Típus:
() => any
Ez az aszimmetrikus matcher, ha egyenlőség ellenőrzéssel használjuk, mindig
true
értéket ad vissza. Akkor hasznos, ha csak azt szeretnéd ellenőrizni, hogy egy adott tulajdonság létezik-e.tsimport { expect, test } from 'vitest'; test('az objektumnak van "apples" kulcsa', () => { expect({ apples: 22 }).toEqual({ apples: expect.anything() }); });
expect.any
Típus:
(constructor: unknown) => any
Ez az aszimmetrikus matcher, ha egyenlőség ellenőrzéssel használjuk, csak akkor ad vissza
true
értéket, ha az érték egy megadott konstruktor példánya. Akkor hasznos, ha van egy értéked, ami minden alkalommal generálódik, és csak azt szeretnéd ellenőrizni, hogy a megfelelő típusú-e.tsimport { expect, test } from 'vitest'; import { generateId } from './generators.js'; test('"id" egy szám', () => { expect({ id: generateId() }).toEqual({ id: expect.any(Number) }); });
expect.arrayContaining
Típus:
<T>(expected: T[]) => any
Egyenlőségvizsgálat során ez az aszimmetrikus matcher
true
értéket ad vissza, ha az érték egy tömb, és tartalmazza a megadott elemeket.tsimport { expect, test } from 'vitest'; test('a kosár tartalmaz fuji-t', () => { const basket = { varieties: ['Empire', 'Fuji', 'Gala'], count: 3, }; expect(basket).toEqual({ count: 3, varieties: expect.arrayContaining(['Fuji']), }); });
TIP
Használhatod az
expect.not
-ot ezzel a matcherrel, hogy negáld a várt értéket.
expect.objectContaining
Típus:
(expected: any) => any
Egyenlőségvizsgálat során ez az aszimmetrikus matcher
true
értéket ad vissza, ha az érték egy objektum, és tartalmazza a megadott tulajdonságokat a megadott értékekkel.tsimport { expect, test } from 'vitest'; test('a kosárban van Empire alma', () => { const basket = { varieties: [ { name: 'Empire', count: 1, }, ], }; expect(basket).toEqual({ varieties: [expect.objectContaining({ name: 'Empire' })], }); });
TIP
Használhatod az
expect.not
-ot ezzel a matcherrel, hogy negáld a várt értéket.
expect.stringContaining
Típus:
(expected: any) => any
Egyenlőségvizsgálat során ez az aszimmetrikus matcher
true
értéket ad vissza, ha az érték egy string, és tartalmazza a megadott részstringet.tsimport { expect, test } from 'vitest'; test('az almafajta nevében van "Emp"', () => { const variety = { name: 'Empire', count: 1, }; expect(variety).toEqual({ name: expect.stringContaining('Emp'), count: 1, }); });
TIP
Használhatod az
expect.not
-ot ezzel a matcherrel, hogy negáld a várt értéket.
expect.stringMatching
Típus:
(expected: any) => any
Egyenlőségvizsgálat során ez az aszimmetrikus matcher
true
értéket ad vissza, ha az érték egy string, és megfelel a megadott reguláris kifejezésnek.tsimport { expect, test } from 'vitest'; test('a fajta "re"-re végződik', () => { const variety = { name: 'Empire', count: 1, }; expect(variety).toEqual({ name: expect.stringMatching(/re$/), count: 1, }); });
TIP
Használhatod az
expect.not
-ot ezzel a matcherrel, hogy negáld a várt értéket.
expect.addSnapshotSerializer
Típus:
(plugin: PrettyFormatPlugin) => void
Ezzel a metódussal egyéni szerializálókat adhatsz hozzá, amelyek a pillanatképek (snapshot) létrehozásakor kerülnek meghívásra. Ez egy haladó funkció - ha többet szeretnél tudni, olvasd el az egyéni szerializálókról szóló útmutatót.
Ha egyéni szerializálókat használsz, akkor ezt a metódust a
setupFiles
konfigurációs opcióban kell meghívnod. Ez minden pillanatképre hatással lesz.TIP
Ha korábban a Vue CLI-t használtad a Jest-tel, akkor érdemes lehet telepíteni a jest-serializer-vue csomagot. Ellenkező esetben a pillanatképeid egy stringbe lesznek csomagolva, ami miatt a
"
karakterek escape-elve lesznek.
expect.extend
Típus:
(matchers: MatchersObject) => void
Az alapértelmezett matchereket kibővítheted a sajátjaiddal. Ez a függvény a matcherek objektumának egyéni matcherekkel való bővítésére szolgál.
Ha így definiálsz matchereket, akkor aszimmetrikus matchereket is létrehozol, amelyek az
expect.stringContaining
metódushoz hasonlóan használhatók.tsimport { expect, test } from 'vitest'; test('egyéni matcherek', () => { expect.extend({ toBeFoo: (received, expected) => { if (received !== 'foo') { return { message: () => `azt vártuk, hogy ${received} 'foo' értékű legyen`, pass: false, }; } }, }); expect('foo').toBeFoo(); expect({ foo: 'foo' }).toEqual({ foo: expect.toBeFoo() }); });
TIP
Ha azt szeretnéd, hogy a matchereid minden tesztben elérhetőek legyenek, akkor ezt a metódust a
setupFiles
konfigurációs opcióban kell meghívnod.Ez a függvény kompatibilis a Jest
expect.extend
függvényével, így minden könyvtár, amely ezt használja egyéni matcherek létrehozására, működni fog a Vitest-tel.Ha TypeScript-et használsz, a Vitest 0.31.0 óta kibővítheted az alapértelmezett
Assertion
interfészt egy ambient deklarációs fájlban (pl:vitest.d.ts
) az alábbi kóddal:tsinterface CustomMatchers<R = unknown> { toBeFoo(): R; } declare module 'vitest' { interface Assertion<T = any> extends CustomMatchers<T> {} interface AsymmetricMatchersContaining extends CustomMatchers {} }
WARNING
Ne felejtsd el belefoglalni az ambient deklarációs fájlt a
tsconfig.json
fájlodba.TIP
Ha többet szeretnél tudni, nézd meg az útmutatót a matcherek bővítéséről.