Nor*_*ldt 5 javascript unit-testing reactjs jestjs
在观看了这个关于如何在 React 应用程序中测试 API 调用的示例后,我开始使用msw(模拟服务工作者)。
有什么方法可以监视模拟 Service Worker?
例如:
import React from 'react'
import { render, act, await } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { rest } from 'msw'
import { setupServer } from 'msw/node'
import SearchBox from '.'
const fakeServer = setupServer(
rest.get(
'https://api.flickr.com/services/rest/?method=flickr.photos.search',
(req, res, ctx) => res(ctx.status(200), ctx.json({ data: { photos: { photo: [] },},}))
)
)
beforeAll(() => {fakeServer.listen()})
afterEach(() => {fakeServer.resetHandlers()})
afterAll(() => fakeServer.close())
test('it calls Flickr REST request when submitting search term', async () => {
const { getByLabelText } = render(<SearchBox />)
const input = getByLabelText('Search Flickr')
const submitButton = getByLabelText('Submit search')
await act(async () => {
await userEvent.type(input,'Finding Wally')
await userEvent.click(submitButton)
})
await wait()
// TODO: assert that the fakeServer was called once and with the correct URL
})
Run Code Online (Sandbox Code Playgroud)
要测试的组件如下所示:
import React, { useState } from 'react'
import axios from 'axios'
import './index.css'
function SearchBox({ setPhotos }) {
const [searchTerm, setSearchTerm] = useState('')
const handleTyping = (event) => {
event.preventDefault()
setSearchTerm(event.currentTarget.value)
}
const handleSubmit = async (event) => {
event.preventDefault()
try {
const restURL = `https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=${
process.env.REACT_APP_API_KEY
}&per_page=10&format=json&nojsoncallback=1'&text=${encodeURIComponent(
searchTerm
)}`
const { data } = await axios.get(restURL)
const fetchedPhotos = data.photos.photo
setPhotos(fetchedPhotos)
} catch (error) {
console.error(error)
}
}
return (
<section style={styles.container}>
<form action="" method="" style={styles.form}>
<input
aria-label="Search Flickr"
style={styles.input}
value={searchTerm}
onChange={handleTyping}
/>
<button
aria-label="Submit search"
style={styles.button}
onClick={handleSubmit}
>
SEARCH
</button>
</form>
</section>
)
}
Run Code Online (Sandbox Code Playgroud)
我有一个工作测试,但我觉得它倾向于实施测试,因为它使用间谍 setPhotos
test('it calls Flickr REST request when submitting search term', async () => {
const fakeSetPhotos = jest.fn(() => {})
const { getByLabelText } = render(<SearchBox setPhotos={fakeSetPhotos} />)
const input = getByLabelText('Search Flickr')
const submitButton = getByLabelText('Submit search')
await act(async () => {
await userEvent.type(input, 'Finding Walley')
await userEvent.click(submitButton)
})
await wait()
expect(fakeSetPhotos).toHaveBeenCalledWith([1, 2, 3])
})
Run Code Online (Sandbox Code Playgroud)
小智 5
如果您想避免嘲笑,您可以监视axios.get并断言它被正确调用。
test('it calls Flickr REST request when submitting search term', async () => {
const getSpy = jest.spyOn(axios, 'get');
const { getByLabelText } = render(<SearchBox />)
const input = getByLabelText('Search Flickr')
const submitButton = getByLabelText('Submit search')
await act(async () => {
await userEvent.type(input,'Finding Wally')
await userEvent.click(submitButton)
})
await wait()
expect(getSpy).toHaveBeenCalledTimes(1)
})
Run Code Online (Sandbox Code Playgroud)
mswjs的开发人员非常友善且乐于助人。他们花时间建议我如何处理它。
我得到的当前工作测试很好 - 只是提出了一个替代方案jest.fn()- 我确实喜欢他们建议的可读性:
test('...', async () => {
let photos
// Create an actual callback function
function setPhotos(data) {
// which does an action of propagating given data
// to the `photos` variable.
photos = data
}
// Pass that callback function as a value to the `setPhotos` prop
const { getByLabelText } = render(<SearchBox setPhotos={setPhotos} />)
// Perform actions:
// click buttons, submit forms
// Assert result
expect(photos).toEqual([1, 2, 3])
})
Run Code Online (Sandbox Code Playgroud)
我想测试的另一件事是它实际上调用了一个有效的 REST URL。
您可以在响应解析器中反映无效的查询参数。如果查询参数丢失/无效,您的真实服务器将不会产生预期的数据,对吗?因此,对于 MSW,您的“真实服务器”就是您的响应解析器。检查该查询参数的存在或值,并在该参数无效的情况下引发错误。
Run Code Online (Sandbox Code Playgroud)rest.get('https://api.flickr.com/services/rest/?method=flickr.photos.search', (req, res, ctx) => { const method = req.url.searchParams.get('method') if (!method) { // Consider a missing `method` query parameter as a bad request. return res(ctx.status(400)) } // Depending on your logic, you can also check if the value of the `method` // parameter equals to "flickr.photos.search". return res(ctx.json({ successful: 'response' })) })现在,如果您的应用错过了请求 URL 中的方法查询参数,它将获得 400 响应,并且在此类不成功响应的情况下不应调用 setPhotos 回调。
| 归档时间: |
|
| 查看次数: |
2325 次 |
| 最近记录: |