1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Mock Service Workerの使い方

Posted at

MSWとは何か

MSW(Mock Service Worker)は、ブラウザとNode.js環境でAPIリクエストをインターセプト(横取り)し、モックレスポンスを返すことができるライブラリです。Service Worker APIを活用してネットワークレベルでリクエストを捕捉するため、アプリケーションコードを変更することなくAPIのモッキングが可能です。

なぜMSWが必要なのか

フロントエンド開発では、バックエンドAPIが未完成の状態で開発を進めたり、テスト環境で安定したレスポンスが必要になる場面があります。従来のモック手法では、fetchやaxiosなどのHTTPクライアントを直接モックする必要がありましたが、MSWを使用することで以下のメリットが得られます。

  1. 実装に依存しない: HTTPクライアントの種類(fetch、axios、XMLHttpRequest)に関わらず動作
  2. 本番環境に近い: 実際のネットワークリクエストと同じ挙動を再現
  3. 開発体験の向上: ブラウザの開発者ツールでリクエスト/レスポンスを確認可能

MSWの動作原理

ブラウザ環境での動作

ブラウザでは、Service Workerを登録してネットワークリクエストをインターセプトします。アプリケーションが発行したリクエストは、まずService Workerに到達し、定義されたハンドラーと照合されます。マッチするハンドラーがあればモックレスポンスを返し、なければ実際のネットワークリクエストとして処理されます。

Node.js環境での動作

Node.js環境(Vitestなどのテスト実行時)では、node-request-interceptorライブラリを使用してHTTPモジュールのリクエストをインターセプトします。これにより、テスト環境でも同じハンドラー定義を使用してAPIをモックできます。

基本的なセットアップ

MSWのセットアップは、以下の手順で行います。

1. インストール

npm install msw@2.7.3 --save-dev

2. Service Workerファイルの生成

npx msw init public/ --save

このコマンドでpublic/mockServiceWorker.jsが生成されます。

3. ハンドラーの定義

src/mocks/handlers.tsを作成:

import { http, HttpResponse } from 'msw'

export const handlers = [
  // GETリクエストのモック
  http.get('/api/users', () => {
    return HttpResponse.json([
      { id: 1, name: '田中太郎', email: 'tanaka@example.com' },
      { id: 2, name: '佐藤花子', email: 'sato@example.com' }
    ])
  }),

  // POSTリクエストのモック
  http.post('/api/users', async ({ request }) => {
    const body = await request.json() as { name: string; email: string }
    
    return HttpResponse.json({
      id: 3,
      name: body.name,
      email: body.email
    }, { status: 201 })
  })
]

4. ワーカーの設定

src/mocks/browser.tsを作成:

import { setupWorker } from 'msw/browser'
import { handlers } from './handlers'

export const worker = setupWorker(...handlers)

5. アプリケーションでの初期化

src/main.tsで開発環境時のみMSWを起動:

import { createApp } from 'vue'
import App from './App.vue'

async function enableMocking() {
  if (import.meta.env.MODE !== 'development') {
    return
  }

  const { worker } = await import('./mocks/browser')
  
  return worker.start({
    onUnhandledRequest: 'bypass' // ハンドラーがないリクエストは通常通り処理
  })
}

enableMocking().then(() => {
  createApp(App).mount('#app')
})

より実践的な使い方

動的なレスポンス

パスパラメータやクエリパラメータに基づいて動的なレスポンスを返すことができます。

http.get('/api/users/:id', ({ params }) => {
  const { id } = params
  
  return HttpResponse.json({
    id: Number(id),
    name: `ユーザー${id}`,
    email: `user${id}@example.com`
  })
})

エラーレスポンスのモック

エラー状態のテストも簡単に行えます。

http.get('/api/users/:id', ({ params }) => {
  const { id } = params
  
  if (id === '999') {
    return HttpResponse.json(
      { error: 'ユーザーが見つかりません' },
      { status: 404 }
    )
  }
  
  // 通常のレスポンス
})

遅延レスポンス

ローディング状態のテストのために、意図的に遅延を追加できます。

import { delay } from 'msw'

http.get('/api/users', async () => {
  await delay(2000) // 2秒遅延
  
  return HttpResponse.json([
    // データ
  ])
})

テスト環境での使用

Vitestでの設定例:

src/mocks/server.tsを作成:

import { setupServer } from 'msw/node'
import { handlers } from './handlers'

export const server = setupServer(...handlers)

vitest.setup.tsに以下を追加:

import { beforeAll, afterEach, afterAll } from 'vitest'
import { server } from './src/mocks/server'

beforeAll(() => server.listen())
afterEach(() => server.resetHandlers())
afterAll(() => server.close())

テストファイルでの使用例:

import { describe, it, expect } from 'vitest'
import { server } from '@/mocks/server'
import { http, HttpResponse } from 'msw'

describe('ユーザー一覧', () => {
  it('エラー時の処理を確認', async () => {
    // このテストのみ500エラーを返すように上書き
    server.use(
      http.get('/api/users', () => {
        return HttpResponse.json(
          { error: 'サーバーエラー' },
          { status: 500 }
        )
      })
    )
    
    // エラー処理のテスト
  })
})

まとめ

MSWは、Service Worker APIを活用してネットワークレベルでAPIリクエストをモックする強力なツールです。開発環境でのAPIモッキングからテスト環境での使用まで、一貫した方法でAPIの振る舞いを制御できます。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?