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

4
  • 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. Commented Jul 12, 2022 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. Commented Jul 12, 2022 at 22:22
  • I posted the Favicon error I am getting when I only render the approuter without any router @DrewReese Commented Jul 12, 2022 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: stackoverflow.com/questions/72959161/… @DrewReese Commented Jul 12, 2022 at 22:54

1 Answer 1

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();
});
Sign up to request clarification or add additional context in comments.

1 Comment

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.