javascript - 监视模拟服务人员(msw)?

标签 javascript reactjs unit-testing jestjs

我开始使用 msw (mock service worker)看完this example如何使用它来测试 React 应用程序中的 API 调用。
有什么方法可以监视模拟服务人员?
例如:

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
})
要测试的组件如下所示:
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>
  )
}
我有一个工作测试,但我觉得它倾向于执行测试,因为它在 setPhotos 上使用了一个 spy 。
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])
})

最佳答案

mswjs 的开发人员真的很好,乐于助人。他们花时间to advice我如何处理它。
TLDR;
我得到的当前工作测试很好 - 只是建议了 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])
})
我想测试的另一件事是它实际上调用了一个有效的 REST URL。

You can reflect an invalid query parameter in the response resolver. If the query parameter is missing/invalid your real server would not produce the expected data, right? So with MSW your "real server" is your response resolver. Check the presence or value of that query parameter and raise an error in case that parameter is invalid.

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' })) })

Now, if your app misses the method query parameter in the request URL, it would get a 400 response, and shouldn't call the setPhotos callback in case of such unsuccessful response.

关于javascript - 监视模拟服务人员(msw)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63408769/

相关文章:

javascript - Highcharts : help to create the JSON

javascript - <li><p>text</p></li> 上点击事件中的未定义文本

javascript - 迭代矩形的周长

javascript - 当状态改变时,React-typing-animation 不会重新渲染

javascript - Angular Mocks 破坏了我的应用程序

c# - 有人可以告诉我尝试通过调用工作单元来测试 Controller 时我做错了什么吗?

javascript - 在angularjs中绑定(bind)后无法在文本框中查看值

javascript - 如何在 react 导出中在网页上显示 promise 的结果

javascript - 未捕获的 TypeError : Cannot read property 'nameOfCity' of null at App. 渲染

python - 如何最合理地分解行,在Python中保留 "within 80 chars"?