From 75b8e759c1128a8da6df977d50acf33d2c46d033 Mon Sep 17 00:00:00 2001 From: Vladimir Date: Sat, 28 Mar 2026 09:05:07 +0100 Subject: [PATCH 1/3] chore: remove tinyspy from docs (#9990) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ari Perkkiö --- .vitepress/components/FeaturesList.vue | 2 +- .vitepress/config.ts | 2 +- guide/features.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.vitepress/components/FeaturesList.vue b/.vitepress/components/FeaturesList.vue index 5fa2f5c7..9ab874de 100644 --- a/.vitepress/components/FeaturesList.vue +++ b/.vitepress/components/FeaturesList.vue @@ -22,7 +22,7 @@ import ListItem from './ListItem.vue' Chai built-in for assertions + Jest expect compatible APIs - Tinyspy built-in for mocking + Jest-compatible mocking happy-dom or jsdom for DOM mocking Browser Mode for running component tests in the browser Code coverage via v8 or istanbul diff --git a/.vitepress/config.ts b/.vitepress/config.ts index a1f34635..d57f189d 100644 --- a/.vitepress/config.ts +++ b/.vitepress/config.ts @@ -52,7 +52,7 @@ export default ({ mode }: { mode: string }) => { ['link', { rel: 'icon', href: '/favicon.ico', sizes: '48x48' }], ['link', { rel: 'icon', href: '/logo-without-border.svg', type: 'image/svg+xml' }], ['meta', { name: 'author', content: `${teamMembers.map(c => c.name).join(', ')} and ${vitestName} contributors` }], - ['meta', { name: 'keywords', content: 'vitest, vite, test, coverage, snapshot, react, vue, preact, svelte, solid, lit, marko, ruby, cypress, puppeteer, jsdom, happy-dom, test-runner, jest, typescript, esm, tinyspy, node' }], + ['meta', { name: 'keywords', content: 'vitest, vite, test, coverage, snapshot, react, vue, preact, svelte, solid, lit, marko, ruby, cypress, puppeteer, jsdom, happy-dom, test-runner, jest, typescript, esm, node' }], ['meta', { property: 'og:title', content: vitestName }], ['meta', { property: 'og:description', content: vitestDescription }], ['meta', { property: 'og:url', content: ogUrl }], diff --git a/guide/features.md b/guide/features.md index 9b4cbdd6..f29cdf6d 100644 --- a/guide/features.md +++ b/guide/features.md @@ -106,7 +106,7 @@ Notice that if you are using third-party libraries that add matchers, setting [` ## Mocking -[Tinyspy](https://github.com/tinylibs/tinyspy) is built-in for mocking with `jest`-compatible APIs on `vi` object. +Vitest provides `jest`-compatible APIs on `vi` object. ```ts import { expect, vi } from 'vitest' From a96e7c3fda767f2a71f142bcecff9e42fa9ee18e Mon Sep 17 00:00:00 2001 From: Vladimir Date: Sun, 29 Mar 2026 06:45:52 +0200 Subject: [PATCH 2/3] docs: add example of unhandled error with `expect.toThrow` (#10006) --- api/expect.md | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/api/expect.md b/api/expect.md index c5e02204..c62de312 100644 --- a/api/expect.md +++ b/api/expect.md @@ -860,6 +860,52 @@ test('throws non-Error values', () => { ``` ::: +:::warning Unhandled Rejections with Fake Timers +When using fake timers, an async function that rejects _during_ a `vi.advanceTimersByTimeAsync` call will trigger an [unhandled rejection](https://nodejs.org/api/process.html#event-unhandledrejection) — even if you later assert it with `.rejects.toThrow()`. This happens because the error is thrown before the `expect` chain has a chance to catch it. + +```ts +async function foo() { + await new Promise(resolve => setTimeout(resolve, 100)) + throw new Error('boom') +} + +test('rejects', async () => { + const result = foo() + + await vi.advanceTimersByTimeAsync(100) + + // The assertion passes, but the error was already "unhandled" during advanceTimersByTimeAsync + await expect(result).rejects.toThrow() +}) +``` + +To avoid this, prefer [`vi.setTimerTickMode('nextTimerAsync')`](/api/vi#vi-settimertickmode) so that timers tick automatically as promises settle, without needing a manual advance: + +```ts +beforeEach(() => { + vi.useFakeTimers() + vi.setTimerTickMode('nextTimerAsync') +}) + +test('rejects', async () => { + // No advanceTimersByTimeAsync needed — the error is caught by rejects.toThrow() + await expect(foo()).rejects.toThrow('boom') +}) +``` + +Alternatively, set up the `.rejects.toThrow()` assertion _before_ advancing timers so the rejection is handled immediately: + +```ts +test('rejects', async () => { + const result = foo() + const assertion = expect(result).rejects.toThrow('boom') + + await vi.advanceTimersByTimeAsync(100) + await assertion +}) +``` +::: + ## toMatchSnapshot - **Type:** `(shape?: Partial | string, hint?: string) => void` From a0d8d65dd9426589dd485c0db26eb771f5db3aaf Mon Sep 17 00:00:00 2001 From: noise Date: Mon, 30 Mar 2026 09:16:39 +0800 Subject: [PATCH 3/3] docs(cn): dissolve the conflict --- .vitepress/components/FeaturesList.vue | 16 +--------------- api/expect.md | 2 +- guide/features.md | 6 +----- 3 files changed, 3 insertions(+), 21 deletions(-) diff --git a/.vitepress/components/FeaturesList.vue b/.vitepress/components/FeaturesList.vue index 0734b958..82526fba 100644 --- a/.vitepress/components/FeaturesList.vue +++ b/.vitepress/components/FeaturesList.vue @@ -9,7 +9,6 @@ import ListItem from './ListItem.vue' Vite 通用的配置、转换器、解析器和插件。 -<<<<<<< HEAD 使用与你的应用相同的设置来运行测试! 智能文件监听模式,就像是测试的 HMR! 支持对 Vue、React、Svelte、Lit 等框架进行组件测试。 @@ -37,9 +36,7 @@ import ListItem from './ListItem.vue' Jest expect API - 内置 - Tinyspy 用于对象 - Mock + 兼容 Jest 对象模拟 使用 @@ -65,17 +62,6 @@ import ListItem from './ListItem.vue' 支持分片执行 报告未捕获的错误 -======= - Chai built-in for assertions + Jest expect compatible APIs - Jest-compatible mocking - happy-dom or jsdom for DOM mocking - Browser Mode for running component tests in the browser - Code coverage via v8 or istanbul - Rust-like in-source testing - Type Testing via expect-type - Sharding Support - Reporting Uncaught Errors ->>>>>>> a96e7c3fda767f2a71f142bcecff9e42fa9ee18e diff --git a/api/expect.md b/api/expect.md index 663fb3a1..1ec7ba5b 100644 --- a/api/expect.md +++ b/api/expect.md @@ -861,7 +861,7 @@ test('throws non-Error values', () => { }) ``` ::: - + :::warning Unhandled Rejections with Fake Timers When using fake timers, an async function that rejects _during_ a `vi.advanceTimersByTimeAsync` call will trigger an [unhandled rejection](https://nodejs.org/api/process.html#event-unhandledrejection) — even if you later assert it with `.rejects.toThrow()`. This happens because the error is thrown before the `expect` chain has a chance to catch it. diff --git a/guide/features.md b/guide/features.md index 9c14c1d6..3dc5411d 100644 --- a/guide/features.md +++ b/guide/features.md @@ -120,11 +120,7 @@ it('renders correctly', () => { ## 对象模拟 (Mocking) {#mocking} -<<<<<<< HEAD -内置 [Tinyspy](https://github.com/tinylibs/tinyspy) 用于在 `vi` 对象上使用 `jest` 兼容的 API 进行对象模拟。 -======= -Vitest provides `jest`-compatible APIs on `vi` object. ->>>>>>> a96e7c3fda767f2a71f142bcecff9e42fa9ee18e +Vitest 在 `vi` 对象上提供了与 `Jest` 兼容的 API 接口。 ```ts import { expect, vi } from 'vitest'