測試你的 React App 使用 Mock Server
tags: React
Testing
category: Front-End
description: 測試你的 React App 使用 Mock Server
created_at: 2022/01/15 14:00:00
事前準備
- 裝好
Node.js
前言
繼上篇測試之後,這次希望整合 API
做測試,但是有時候又不能去打真的 API
, 那就只能做一個模擬(Mock)
的了。
實作範例
這次做的範例比上次更簡單,我要一個按鈕,點下去之後跟 API
要資料顯示在畫面上
先做一個真實的 API
這邊使用 express
當範例
先建立專案
npm init -y
再來安裝套件
npm i express cors
再來建立 app.js
const express = require('express')
const cors = require('cors')
const app = express()
const port = 8000
app.use(cors())
app.get('/hello', (req, res) => {
res.send('Hello World.')
})
app.listen(port, () => {
console.log(`Listening at http://localhost:${port}`)
})
這樣去跑 node app.js
會看到 API
已經啟動,可以輸入 http://localhost:8000/hello
存取
做前端
import React, { useState } from 'react'
function App() {
const [response, setResponse] = useState(null)
const getResponse = () => {
fetch('http://localhost:8000/hello')
.then((res) => res.text())
.then((data) => {
setResponse(data)
})
}
return (
<div className="App">
<span data-testid="response-span">{response}</span>
<button onClick={getResponse}>Get Response</button>
</div>
)
}
export default App
再來啟動 Server
應該可以看到一個按鈕,點下去之後會去向 API
請求,得到回應後會渲染在畫面上。
寫測試
import { fireEvent, render, screen, waitFor } from '@testing-library/react'
import React from 'react'
import App from './App'
test('get response button function', async () => {
render(<App />)
const buttonElement = screen.getByRole('button', { name: 'Get Response' })
fireEvent.click(buttonElement)
const spanElement = screen.getByTestId('response-span')
await waitFor(() => expect(spanElement.textContent).toBe('Hello World.'))
})
然後跑測試,會發現 PASS
,但是這樣實際去向 API
發了請求,如果我們 API
有對資料庫做操作或一些不可逆的操作將會引來災難,所以我們需要一個模擬(Mock)
的 API
使用 Mock Service Worker
安裝
$ npm install msw --save-dev
# or
$ yarn add msw --dev
建立 src/mocks/handlers.js
import { rest } from 'msw'
export const handlers = [
rest.get(`http://localhost:8000/hello`, (req, res, ctx) => {
return res(ctx.status(200), ctx.text('Hello World.'))
}),
]
再來到 src/setupTests.js
加上相關設定
// ...
import { handlers } from 'mocks/handlers'
import { setupServer } from 'msw/node'
const server = setupServer(...handlers)
beforeAll(() => server.listen())
afterEach(() => server.resetHandlers())
afterAll(() => server.close())
再來跑測試會看到類似下面這樣
PASS src/App.test.js
√ get response button function (100 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 1.191 s
Ran all test suites.
這樣就完成了,如果你要確認的話可以在 API
塞 Log
或是故意把 Mock API
回傳的資料改變,讓他失敗。
最後更新時間: 2022年01月15日.