使用Jest在React(Vite)中模拟fetch请求

gt0wga4j  于 2023-06-04  发布在  Jest
关注(0)|答案(1)|浏览(184)

我有以下组件,它从API request获取数据并将其传递给另一个组件。

import { useState, useEffect } from 'react'
import Loading from './Loading'
import Tours from './Tours'

const url = 'https://course-api.com/react-tours-project'

const App = () => {
  const [isLoading, setIsLoading] = useState(true)
  const [tours, setTours] = useState([])

  const removeTour = (id) => {
    const newTours = tours.filter((tour) => tour.id !== id)
    setTours(newTours)
  }

  const fetchTours = async () => {
    setIsLoading(true)
    try {
      const response = await fetch(url)
      const tours = await response.json()
      setTours(tours)
    } catch (error) {
      console.log(error)
    }
    setIsLoading(false)
  }
  useEffect(() => {
    fetchTours()
  }, [])

  if (isLoading) {
    return (
      <main>
        <Loading />
      </main>
    )
  }
  // TODO

  if (tours.length === 0) {
    return (
      <main>
        <div className='title'>
          <h2>no tours left</h2>
          <button className='btn' onClick={() => fetchTours()}>
            refresh
          </button>
        </div>
      </main>
    )
  }
  return (
    <main>
      <Tours tours={tours} removeTour={removeTour} />
    </main>
  )
}
export default App

接下来我想用Jest模拟这个请求。

import React from 'react'
import '@testing-library/jest-dom'
import App from './App'

describe('App', () => {
  beforeEach(() => {
    jest.spyOn(global, 'fetch').mockResolvedValue({
      json: jest.fn().mockResolvedValue([
        {
          id: 'rec6d6T3q5EBIdCfD',
          name: 'Best of Paris in 7 Days Tour',
          info: "Paris is synonymous with the finest things that culture can offer — in art, fashion, food, literature, and ideas. On this tour, your Paris-savvy Rick Steves guide will immerse you in the very best of the City of Light: the masterpiece-packed Louvre and Orsay museums, resilient Notre-Dame Cathedral, exquisite Sainte-Chapelle, and extravagant Palace of Versailles. You'll also enjoy guided neighborhood walks through the city's historic heart as well as quieter moments to slow down and savor the city's intimate cafés, colorful markets, and joie de vivre. Join us for the Best of Paris in 7 Days!",
          image: 'https://www.course-api.com/images/tours/tour-1.jpeg',
          price: '1,995',
        },
      ]),
    })
  })

  afterEach(() => {
    global.fetch.mockRestore()
  })

  it('fetches and renders data', async () => {
    await act(async () => {
      const { getByText } = render(<App />)

      // Wait for the data to be fetched and rendered
      await new Promise((resolve) => setTimeout(resolve, 0))

      // Verify that the fetch function was called with the correct URL
      expect(global.fetch).toHaveBeenCalledWith(
        'https://api.example.com/datahttps://course-api.com/react-tours-project'
      )

      // Verify that the fetched data is rendered
      expect(getByText('Test Data')).toBeInTheDocument()
    })
  })
})
module.exports = {
  // ... other configuration options
  transform: {
    '^.+\\.jsx?$': 'babel-jest',
  },
}

当我运行测试时,我得到了这个错误。

FAIL  src/App.test.js
  ● Test suite failed to run

    Jest encountered an unexpected token

    Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.

    Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.

    By default "node_modules" folder is ignored by transformers.

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
     • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/configuration
    For information about custom transformations, see:
    https://jestjs.io/docs/code-transformation

    Details:

    /Users/theodosiostziomakas/Desktop/Udemy/React Tutorial and Project Course (2022)/react-course-v3/04-fundamental-projects/02-tours/starter/src/App.test.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import React from 'react';
                                                                                      ^^^^^^

    SyntaxError: Cannot use import statement outside a module

为什么会这样?

fykwrbwg

fykwrbwg1#

通常你想模拟返回值。像这样

const data = { hello: 'world' };
const response = { json: jest.fn().mockResolvedValue(data) };
global.fetch = jest.fn().mockResolvedValue(response);

相关问题