5

About:

Hey there, at the moment I am trying to write tests with jest and the react testing library for my react components. I also use react-router.

The Problem:

I want to check if the app routes to the right component when the path changes without interacting with the single components.

So for example, if the current pathname is "/impressum" I want to have a Snapshot from just the Impressum page.

I cannot figure out how to pass the path to <App> so that only one Route is displayed.

The component I am trying to test:

import React from 'react'
import { BrowserRouter as Router, Switch, Route } from "react-router-dom"

import WeatherPage from "../WeatherPage/WeatherPage.js"
import AddWeatherPage from "../AddWeatherPage/AddWeatherPage.js"
import WeatherDetailsPage from "../WeatherDetailsPage/WeatherDetailsPage.js"
import DeleteWeatherPage from '../DeleteWeatherPage/DeleteWeatherPage.js'
import ImpressumPage from '../ImpressumPage/ImpressumPage.js'

class App extends React.Component {
  render() {
    return (
      <Router>
        <Switch>
          <Route path="/weatherDetails" component={WeatherDetailsPage} />
          <Route path="/addWeather" component={AddWeatherPage} />
          <Route path="/deleteWeather" component={DeleteWeatherPage} />
          <Route path="/impressum" component={ImpressumPage} />
          <Route path="/" component={WeatherPage} />
        </Switch>
      </Router>
    );
  }
}

export default App

What i tried:

  1. So I already tried to implement the following example: https://testing-library.com/docs/example-react-router

  2. I also tried to wrap the <App> component with <MemoryRouter> from -> import { MemoryRouter } from 'react-router'; and push the route: https://reacttraining.com/react-router/web/guides/testing

  3. I also tried to wrap the <App> component with <Router> from -> import { Router } from "react-router-dom"; and push the history object.

My Basic Testing Code

Following you can see the code I use for testing, I made some changes while testing but this basic part remained all the time.

describe("snapshot-test", () => {
    it("renders component", () => {
        const { asFragment } = render(
            <App></App>
        )

        expect(asFragment()).toMatchSnapshot()
    })
})

2 Answers2

6

I just found a solution.

I had to mock Router to be a div and contains its children code. This works the following way:

You need the folder __mocks__/react-router-dom.js which contains the following code:

import React from 'react';

const reactRouterDom = require("react-router-dom")
reactRouterDom.BrowserRouter = ({children}) => <div>{children}</div>

module.exports = reactRouterDom

Now you can use the MemoryRouter to define the path which the Route should point to.

App.test.js:

import React from "react";
import { render } from "@testing-library/react";
import { MemoryRouter } from 'react-router-dom';
import App from './App';


describe("unit-test", () => {
    it("renders the right component with following path '/impressum'", () => {
        const { getByTestId } = render(
            <MemoryRouter initialEntries={['/impressum']}>
                <App></App>
            </MemoryRouter>
        )

        let impressumPage = getByTestId("impressum-page")

        expect(impressumPage).toBeInTheDocument()
    })
})

Also visit the following link, I got the solution from there. https://medium.com/@antonybudianto/react-router-testing-with-jest-and-enzyme-17294fefd303

0

I think you need to put exact before the path of the '/' like this

<Switch>
      <Route path="/weatherDetails" component={WeatherDetailsPage} />
      <Route path="/addWeather" component={AddWeatherPage} />
      <Route path="/deleteWeather" component={DeleteWeatherPage} />
      <Route path="/impressum" component={ImpressumPage} />
      <Route exact path="/" component={WeatherPage} />
</Switch>

like this is mean that only if you have this path="/" the WeatherPage show i you add to it like path="/impressum" you will see only ImpressumPage. hope it help you :)

TalOrlanczyk
  • 1,205
  • 7
  • 21
  • Thanks for your fast answer. Unfortunately, it didn't work. Further when you do not use the `exact` and the Route is listed at last (the order matters here). Then the "/" path will catch everything which does not include one of the other paths. So when `` would be written first, every Route would display to WeatherPage. But when it is written last, everything which is not the exact path "/weatherDetails", "/addWeather" and so on, displays the WeatherPage component. I think my code does not work because of the tag. – Benjamin Lichtenstein May 24 '20 at 09:57