0

I have the following component which fetches data from an API request and pass them to another component.

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

Next I want to mock the request using 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',
  },
}

When I run the test I am getting this error.

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

Why is this happening?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Theo
  • 3,099
  • 12
  • 53
  • 94
  • This question comes up too frequently: https://stackoverflow.com/questions/58613492/how-to-resolve-cannot-use-import-statement-outside-a-module-from-jest-when-run – morganney May 29 '23 at 19:23

1 Answers1

0

Usually you wanna mock the returned value. like this

const data = { hello: 'world' };
const response = { json: jest.fn().mockResolvedValue(data) };
global.fetch = jest.fn().mockResolvedValue(response);
Moïse Gui
  • 67
  • 2