reactjs – How to test React.js page that uses Context and useEffect?

I’m having trouble testing a page that has Context and useEffect using Jest and Testing-library, can you help me?

REPO: github.com/jefferson1104/padawan

My Context: src/context/personContext.tsx

import { createContext, ReactNode, useState } from 'react'
import { useRouter } from 'next/router'

import { api } from '../services/api'

type PersonData = {
  name?: string
  avatar?: string
}

type PersonProviderProps = {
  children: ReactNode
}

type PersonContextData = {
  person: PersonData
  loading: boolean
  handlePerson: () => void
}

export const PersonContext = createContext({} as PersonContextData)

export function PersonProvider({ children }: PersonProviderProps) {
  const [person, setPerson] = useState<PersonData>({})
  const [loading, setLoading] = useState(false)
  const router = useRouter()

  function checkAvatar(name: string): string {
    return name === 'Darth Vader'
      ? '/img/darth-vader.png'
      : '/img/luke-skywalker.png'
  }

  async function handlePerson() {
    setLoading(true)
    const promise1 = api.get('/1')
    const promise2 = api.get('/4')

    Promise.race([promise1, promise2]).then(function (values) {
      const data = {
        name: values.data.name,
        avatar: checkAvatar(values.data.name)
      }

      setPerson(data)
      setLoading(false)
      router.push('/battlefield')
    })
  }

  return (
    <PersonContext.Provider value={{ person, handlePerson, loading }}>
      {children}
    </PersonContext.Provider>
  )
}

My Page: src/pages/battlefield.tsx

import { useContext, useEffect } from 'react'
import { useRouter } from 'next/router'

import { PersonContext } from '../context/personContext'
import Person from '../components/Person'

const Battlefield = () => {
  const { person } = useContext(PersonContext)
  const router = useRouter()

  useEffect(() => {
    if (!person.name) {
      router.push("https://stackoverflow.com/")
    }
  })

  return <Person />
}

export default Battlefield

My Test: src/tests/pages/Battlefield.spec.tsx

import { render, screen } from '@testing-library/react'

import { PersonContext } from '../../context/personContext'
import Battlefield from '../../pages'

jest.mock('../../components/Person', () => {
  return {
    __esModule: true,
    default: function mock() {
      return <div data-test-id="person" />
    }
  }
})

describe('Battlefield page', () => {
  it('renders correctly', () => {
    const mockPerson = { name: 'Darth Vader', avatar: 'darth-vader.png' }
    const mockHandlePerson = jest.fn()
    const mockLoading = false

    render(
      <PersonContext.Provider
        value={{
          person: mockPerson,
          handlePerson: mockHandlePerson,
          loading: mockLoading
        }}
      >
        <Battlefield />
      </PersonContext.Provider>
    )

    expect(screen.getByTestId('person')).toBeInTheDocument()
  })
})

PRINSCREEN ERROR
enter image description here

Read more here: Source link