0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

mswを使って、requestをinterceptしてmocked responseする!

Last updated at Posted at 2023-03-09

mswはAPIモーキングライブラリで、サーバーに向けたネットワーク要求をインターセプトして模擬応答(mocked response)を返す役割を果たします。

下の写真は、ブラウザがrequestを送るとservice workerがキャッチして、MSWを通してモッキングされたレスポンスをブラウザに送ります。
実際は、実物のAPIサーバからレスポンスを受けるが正しいだが、MSWを使ってリクエストをキャッチして任意のレスポンスを返すことができます。
そのrequestは実際のサーバーではないmswに送った後、登録されたhandlerを通じて模擬応答をクライアントに送ります。
image.png

msw setup

msw package install
npm install msw --save
service worker登録
npx msw init public/ --save

publicのフォルダにmockServiceWorkerファイルを生成してくれるcommandです。
/public/mockServiceWorker.jsとは、ファイルができ、そのファイルがサービス・ウォーカーにmockサーバーを登録させます。このファイルはネットワークの要求をinterceptできるように設計されたservice worker apiを活用します。

browser.js定義

setupWorker()関数を使用してservice workerを生成します。関数の買収はhandler.jsに定義したハンドラを渡します。

src/mocks/browser.js
import { setupWorker } from 'msw'
import { handlers } from './handlers'

export const worker = setupWorker(...handlers); //定義handler登録

handlers.js定義

handlers.jsは要求が入って来た時、模擬の回答をしてくれるハンドラ(handler)コードを作成しなければなりません。
下のコードは、login requestと...raw.githubu...requestをinterceptしてmockingしています。

src/mocks/handlers.js
import { rest } from 'msw'

export const handlers = [
    rest.get('/login', async (req, res, ctx) => {
            return res(
      ctx.json({
        id: 'f79e82e8-c34a-4dc7-a49e-9fadc0979fda',
        firstName: 'John',
        lastName: 'Maverick',
      })
    )
    }),
    rest.get('https://raw.githubusercontent.com/techoi/raw-data-api/main/simple-api.json', async (req, res, ctx) => { // interceptするURLを入力!
        return res(
          {
	"data": {
		"people" :
		[
			{
				"name": "jung",
				"age": 135
			},
			{
				"name": "yeounjae",
				"age": 13
			},
			{
				"name": "cindy",
				"age": 15
			},
			{
				"name": "judy",
				"age": 25
			},
			{
				"name": "marry",
				"age": 64
			},
			{
				"name": "tommy",
				"age": 109
			}
		]
	}
}
            )
        )  
    })
]

index.js定義

index.jsにはweb applicationが実行されるとき、service workerも実行されるようにしたコードを追加します。
src/index.js
// Start the mocking conditionally.
// service mockを実行されるコード!
if (process.env.NODE_ENV === 'development') {
  const { worker } = require('./mocks/browser')
  worker.start()
}

Mockingテスト

TestMocking.jsx
import React, {useState} from 'react'
const Item = ({ name, age }) => {
    return (
        <li>
            name : {name} /age : {age}
        </li>
    );
}
const url =
    "https://raw.githubusercontent.com/techoi/raw-data-api/main/simple-api.json";
export default function TestMocking() {
    const [data, setData] = useState(null);
    const [error, setError] = useState(null);

    const handleClick = () => {
        fetch(url)
            .then((response) => {
                return response.json();
            })
            .then((json) => {
                setData(json.data);
            })
            .catch((error) => {
                setError(`something wrong: ${error}`);
            })
    }

        const handleClick2 = () => {
            fetch('/login')
                .then((response) => {
                    return response.json()
                })
                .then((json) => {
                    console.log(JSON.stringify(json));
                })
    }
    if (error) {
        return <p>{error}</p>
    }
    return (
        <div>
            <button onClick={handleClick}>データ呼び出し1</button>
            <button onClick={handleClick2}>データ呼び出し2</button>
            {data && (
                <ul>
                    {data.people.map((person) => (
                        <Item
                            key={`${person.name}-${person.age}`}
                            name={person.name}
                            age={person.age}
                        />
                    ))}
                </ul>
            )
            }
        </div>
    );
}

「データ呼び出し1」ボタンを押下すると、変数urlを fetchします。
変数urlのJson値は以下になります。

https://raw.githubusercontent.com/techoi/raw-data-api/main/simple-api.json
{
	"data": {
		"people" :
		[
			{
				"name": "jimmy",
				"age": 135
			},
			{
				"name": "timmy",
				"age": 13
			},
			{
				"name": "cindy",
				"age": 15
			},
			{
				"name": "judy",
				"age": 25
			},
			{
				"name": "marry",
				"age": 64
			},
			{
				"name": "tommy",
				"age": 109
			}
		]
	}
}

しかし!handerls.jsに変数url requestに対してintercept定義しておいたため、結果は以下になります。
image.png

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?