Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,14 @@ export default ({ mode }: { mode: string }) => {
text: 'sequence',
link: '/config/sequence',
},
{
text: 'tags',
link: '/config/tags',
},
{
text: 'strictTags',
link: '/config/stricttags',
},
{
text: 'typecheck',
link: '/config/typecheck',
Expand Down Expand Up @@ -772,6 +780,10 @@ export default ({ mode }: { mode: string }) => {
text: '测试筛选',
link: '/guide/filtering',
},
{
text: '测试标签',
link: '/guide/test-tags',
},
{
text: '测试上下文',
link: '/guide/test-context',
Expand Down
2 changes: 2 additions & 0 deletions .vitepress/scripts/cli-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ const skipConfig = new Set([
'browser.name',
'browser.fileParallelism',
'clearCache',
'tagsFilter',
'listTags',
])

function resolveOptions(options: CLIOptions<any>, parentName?: string) {
Expand Down
6 changes: 6 additions & 0 deletions api/advanced/test-case.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,18 @@ interface TaskOptions {
readonly shuffle: boolean | undefined
readonly retry: number | undefined
readonly repeats: number | undefined
readonly tags: string[] | undefined
readonly timeout: number | undefined
readonly mode: 'run' | 'only' | 'skip' | 'todo'
}
```

收集测试时使用的选项。

## tags <Version>4.1.0</Version> {#tags}

隐式或显式分配给测试的 [标签](/guide/test-tags)。

## ok

```ts
Expand Down
7 changes: 6 additions & 1 deletion api/advanced/test-specification.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ const specification = project.createSpecification(
testLines: [20, 40],
testNamePattern: /hello world/,
testIds: ['1223128da3_0_0_0', '1223128da3_0_0'],
} // optional test filters
testTagsFilter: ['frontend and backend'],
} // 可选的测试过滤器
)
```

Expand Down Expand Up @@ -84,6 +85,10 @@ A regexp that matches the name of the test in this module. This value will overr

The ids of tasks inside of this specification to run.

## testTagsFilter <Version>4.1.0</Version> {#testtagsfilter}

The [tags filter](/guide/test-tags#syntax) that a test must pass in order to be included in the run. Multiple filters are treated as `AND`.

## toJSON

```ts
Expand Down
1 change: 1 addition & 0 deletions api/advanced/test-suite.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ interface TaskOptions {
readonly shuffle: boolean | undefined
readonly retry: number | undefined
readonly repeats: number | undefined
readonly tags: string[] | undefined
readonly mode: 'run' | 'only' | 'skip' | 'todo'
}
```
Expand Down
7 changes: 7 additions & 0 deletions api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,15 @@ interface TestOptions {
* @default 0
*/
repeats?: number
/**
* Custom tags of the test. Useful for filtering tests.
*/
tags?: string[] | string
}
```
<!-- TODO: translation -->

<!-- TODO: rewrite this into separate test files with options highlighted -->

当测试函数返回一个 promise 时,运行器会等待它解析结束收集异步的结果。如果 promise 被拒绝,测试就会失败。

Expand Down
43 changes: 43 additions & 0 deletions api/mock.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,49 @@ fn.length // == 2
以下类型中的自定义函数实现使用泛型 `<T>` 进行标记。
:::

<!-- TODO: translation -->

::: warning Class Support {#class-support}
Shorthand methods like `mockReturnValue`, `mockReturnValueOnce`, `mockResolvedValue` and others cannot be used on a mocked class. Class constructors have [unintuitive behaviour](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/constructor) regarding the return value:

```ts {2,7}
const CorrectDogClass = vi.fn(class {
constructor(public name: string) {}
})

const IncorrectDogClass = vi.fn(class {
constructor(public name: string) {
return { name }
}
})

const Marti = new CorrectDogClass('Marti')
const Newt = new IncorrectDogClass('Newt')

Marti instanceof CorrectDogClass // ✅ true
Newt instanceof IncorrectDogClass // ❌ false!
```

Even though the shapes are the same, the _return value_ from the constructor is assigned to `Newt`, which is a plain object, not an instance of a mock. Vitest guards you against this behaviour in shorthand methods (but not in `mockImplementation`!) and throws an error instead.

If you need to mock constructed instance of a class, consider using the `class` syntax with `mockImplementation` instead:

```ts
mock.mockReturnValue({ hello: () => 'world' }) // [!code --]
mock.mockImplementation(class { hello = () => 'world' }) // [!code ++]
```

If you need to test the behaviour where this is a valid use case, you can use `mockImplementation` with a `constructor`:

```ts
mock.mockImplementation(class {
constructor(name: string) {
return { name }
}
})
```
:::

## getMockImplementation

```ts
Expand Down
13 changes: 12 additions & 1 deletion api/vi.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ function mocked<T>(

TypeScript 的类型助手。只返回传入的对象。

当 `partial` 为 `true` 时,它将期望一个 `Partial<T>` 作为返回值。默认情况下,这只会让 TypeScript 认为第一层的值是模拟的。我们可以将 `{ deep: true }` 作为第二个参数传递给 TypeScript,告诉它整个对象都是模拟的(如果实际上是的话)。
当 `partial` 为 `true` 时,它将期望一个 `Partial<T>` 作为返回值。默认情况下,这只会让 TypeScript 认为第一层的值是模拟的。我们可以将 `{ deep: true }` 作为第二个参数传递给 TypeScript,告诉它整个对象都是模拟的(如果实际上是的话)。还可以传递 `{ partial: true, deep: true }` 来使嵌套对象也以递归方式进行部分模拟。

```ts [example.ts]
export function add(x: number, y: number): number {
Expand All @@ -267,6 +267,10 @@ export function add(x: number, y: number): number {
export function fetchSomething(): Promise<Response> {
return fetch('https://vitest.dev/')
}

export function getUser(): { name: string; address: { city: string; zip: string } } {
return { name: 'John', address: { city: 'New York', zip: '10001' } }
}
```

```ts [example.test.ts]
Expand All @@ -286,6 +290,13 @@ test('mock return value with only partially correct typing', async () => {
})
// vi.mocked(example.someFn).mockResolvedValue({ ok: false }) // 这是一个错误类型
})

test('mock return value with deep partial typing', async () => {
vi.mocked(example.getUser, { partial: true, deep: true }).mockReturnValue({
address: { city: 'Los Angeles' },
})
expect(example.getUser().address.city).toBe('Los Angeles')
})
```

### vi.importActual
Expand Down
37 changes: 37 additions & 0 deletions config/stricttags.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
title: strictTags | Config
outline: deep
---

<!-- TODO: translation -->

# strictTags <Version>4.1.0</Version> {#stricttags}

- **Type:** `boolean`
- **Default:** `true`
- **CLI:** `--strict-tags`, `--no-strict-tags`

Should Vitest throw an error if test has a [`tag`](/config/tags) that is not defined in the config to avoid silently doing something surprising due to mistyped names (applying the wrong configuration or skipping the test due to a `--tags-filter` flag).

Note that Vitest will always throw an error if `--tags-filter` flag defines a tag not present in the config.

For example, this test will throw an error because the tag `fortnend` has a typo (it should be `frontend`):

::: code-group
```js [form.test.js]
test('renders a form', { tags: ['fortnend'] }, () => {
// ...
})
```
```js [vitest.config.js]
import { defineConfig } from 'vitest/config'

export default defineConfig({
test: {
tags: [
{ name: 'frontend' },
],
},
})
```
:::
Loading