1

Testing a router component and when I call the screen.debug() in a test after rendering, the DOM output is not what I expected. Why?

Test:

import { render, userEvent as user, screen, getByRole } from '@testing-library/react'
import { Router } from 'react-router-dom'
import { createMemoryHistory } from 'history'
import AppRouter from '../router'

test('Renders AppRouter', () => {
    const history = createMemoryHistory({ initialEntries: ['/post'] })
    render(() => (
        <Router history={history}>
            <AppRouter />
        </Router>
    ))
    
    screen.debug()
})

Component:

import { BrowserRouter, Switch, Route, Redirect } from 'react-router-dom'
import { useState } from 'react'

import useLocalStorage from './hooks/useLocalStorage'
import * as Constants from './constants'

import Header from './layout/header/header'
import MainPage from './pages/mainPage/mainPage'
import PostPage from './pages/postPage/postPage'
import UserPage from './pages/userPage/userPage'
import LoginPage from './pages/loginPage/loginPage'
import SignupPage from './pages/signupPage/signupPage'
import NewPage from './pages/newPage/newPage'
import FeedbackPage from './pages/feedbackPage/feedbackPage'
import AdminPage from './pages/adminPage/adminPage'
import SettingPage from './pages/settingPage/settingPage'

import { WebContext } from './context/WebContext'
import Favicon from 'react-favicon'

const AppRouter = () => {
    const [adminCode, setAdminCode] = useLocalStorage('admin', '')
    const [isMenuOpen, setIsMenuOpen] = useState(false)
    const [page, setPage] = useState(Constants.Page.Home)

    return (
        <BrowserRouter>
            <div role="hello">
                <Favicon url={require('../public/favicon.ico')} />
                <WebContext.Provider
                    value={{
                        isMenuOpen,
                        setIsMenuOpen,
                        page,
                        setPage,
                        adminCode,
                        setAdminCode,
                    }}
                >
                    <Header />
                    <h1>
                        hello
                    </h1>

                    <Switch>
                        <Route component={MainPage} path="/" exact={true} />
                        <Route component={PostPage} path="/post/:id" />
                        <Route component={UserPage} path="/user" />
                        <Route component={LoginPage} path="/login" />
                        <Route component={SignupPage} path="/signup" />
                        <Route component={NewPage} path="/new" />
                        <Route component={FeedbackPage} path="/feedback" />
                        <Route component={AdminPage} path="/admin" />
                        <Route component={SettingPage} path="/setting" />
                        <Route component={() => <Redirect to="/" />} />
                    </Switch>
                </WebContext.Provider>
            </div>
        </BrowserRouter>
    )
}

export default AppRouter

Code-Trace: enter image description here

EDIT

Error when not passing in a function to render: enter image description here

Favicon error: enter image description here

AAMCODE
  • 415
  • 1
  • 7
  • 20
  • 1
    `AppRouter` renders a `BrowserRouter`. Why are you wrapping it in another router component? Try rendering the component you are trying to test into only a single router. – Drew Reese Jul 12 '22 at 21:55
  • You're totally correct. There is no need for the router here at all. The problem I was running into without the router was that the Favicon component in the AppRouter component was throwing an error because Jest cannot read the URL prop. – AAMCODE Jul 12 '22 at 22:22
  • I posted the Favicon error I am getting when I only render the approuter without any router @DrewReese – AAMCODE Jul 12 '22 at 22:25
  • Lol this was totally a case of me starting at my screen for too long. I made another post specifying the issue I am facing before I started playing around with the router: https://stackoverflow.com/questions/72959161/jest-warning-failed-prop-type-invalid-prop-url-supplied-to-favicon-expect @DrewReese – AAMCODE Jul 12 '22 at 22:54

1 Answers1

1

You are passing a function to the test render function when it's expecting JSX.

Remove the function definition and just pass the Router and AppRouter as JSX.

Example:

test('Renders AppRouter', () => {
  const history = createMemoryHistory({ initialEntries: ['/post'] });

  render(
    <Router history={history}>
      <AppRouter />
    </Router>
  );

  screen.debug();
});
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • Yes, but when I do that for this component I get a `TypeError: symbol is not a function`. I edited the original post with the example you provided and the following error output. – AAMCODE Jul 12 '22 at 21:49