Vitest 浏览器模式

将 Mock Service Worker 与 Vitest 浏览器模式集成。

Vitest 浏览器模式 是一款出色的工具,可用于在实际浏览器中测试 UI 组件。将 MSW 与浏览器模式集成时,需要考虑以下几点:

¥Vitest Browser Mode is a fantastic tool for testing your UI components in the actual browser. There are a few things to consider when integrating MSW with the Browser Mode:

  • 顾名思义,你的浏览器模式测试在实际浏览器中运行。这意味着你将使用 MSW 的 浏览器集成(即 setupWorker());

    ¥As the name suggests, your Browser Mode tests run in the actual browser. This means you will be using the Browser integration of MSW (i.e. setupWorker());

  • 你无法重用应用级集成(例如,在你的 main.tsx 中),因为你通常不会在组件测试期间渲染整个组件树。不过,你仍然可以依靠该集成使用 MSW 进行本地开发;

    ¥You cannot reuse the app-level integration (e.g. in your main.tsx) because you don’t normally render your entire component tree during component testing. You can still rely on that integration for local development with MSW though;

  • Vitest 实际上内置了 MSW,但是,截至撰写本文时,你无法直接访问 Vitest 创建的 worker 实例。未来可能会有所变化。

    ¥Vitest actually ships with MSW built-in, however, as of the time writing this, you cannot directly access the worker instance created by Vitest. This may change in the future.

示例

¥Example

我们建议通过 扩展测试上下文 将 MSW 与 Vitest 浏览器模式集成。

¥We recommend integrating MSW with Vitest Browser Mode by extending the test context.

// test-extend.ts
import { test as testBase } from 'vitest'
import { worker } from './mocks/browser.js'
 
export const test = testBase.extend({
  worker: [
    async ({}, use) => {
      // Start the worker before the test.
      await worker.start()
 
      // Expose the worker object on the test's context.
      await use(worker)
 
      // Stop the worker after the test is done.
      worker.stop()
    },
    {
      auto: true,
    },
  ],
})

初始请求处理程序

¥Initial request handlers

现在,任何 test() 都可以针对初始的、快乐路径请求处理程序(例如 handlers.ts 中的处理程序)运行,而无需明确引用 MSW。利用此功能可获得更清晰的测试套件和可预测的基准行为。

¥Any test() now runs against the initial, happy-path request handlers (like those in handlers.ts) without explicitly referencing MSW. Leverage this for cleaner test suites and predictable baseline behavior.

import { test } from './test-extend'
import { Dashboard } from './components/dashboard.js'
 
test('renders the dashboard', () => {
  // Uses only the happy-path request handlers.
  render(<Dashboard />)
 
  // Your actions and assertions...
})

覆盖请求处理程序

¥Overriding request handlers

你可以通过访问测试上下文的 worker 对象并调用 .use() 来执行 覆盖请求处理程序,为其提供应优先处理的请求处理程序:

¥You can override request handlers by accessing the worker object of your test’s context and calling .use(), providing it with the request handlers that should take priority:

import { http, HttpResponse } from 'msw'
import { test } from './test-extend'
import { Dashboard } from './components/dashboard.js'
 
test('displays a notification if fetching the dashboard failed', async ({
  worker,
}) => {
  // Prepend overrides to the happy-path handlers
  // on the `worker` object from the test's context.
  worker.use(
    http.post('/dashboard', () => {
      return new HttpResponse(null, { status: 500 })
    }),
  )
 
  render(<Dashboard />)
 
  // Your actions and assertions...
})