如何测试带有 <Router> 标签的组件?

IT技术 javascript reactjs react-router react-testing-library
2021-05-14 22:50:30

关于:

嘿,目前我正在尝试使用 jest 和 react 测试库为我的 react 组件编写测试。我也使用react-router。

问题:

我想检查当路径更改时应用程序是否路由到正确的组件而不与单个组件交互。

例如,如果当前路径名是“/impressum”,我只想从 Impressum 页面获取快照。

我不知道如何将路径传递到,<App>以便只显示一个 Route。

我正在尝试测试的组件:

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

我试过的:

  1. 所以我已经尝试实现以下示例:https : //testing-library.com/docs/example-react-router

  2. 我还尝试<App>使用<MemoryRouter>from -> import { MemoryRouter } from 'react-router'包装组件并推送路线:https : //reacttraining.com/react-router/web/guides/testing

  3. 我还尝试<App>使用<Router>from -> import { Router } from "react-router-dom"包装组件并推送历史对象。

我的基本测试代码

下面你可以看到我用于测试的代码,我在测试时做了一些更改,但这个基本部分一直保持不变。

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

        expect(asFragment()).toMatchSnapshot()
    })
})
2个回答

我刚刚找到了一个解决方案。

我不得不将 Router 模拟为一个 div 并包含它的子代码。这按以下方式工作:

您需要__mocks__/react-router-dom.js包含以下代码的文件夹

import React from 'react';

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

module.exports = reactRouterDom

现在您可以使用MemoryRouter来定义Route应该指向的路径

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()
    })
})

另请访问以下链接,我从那里得到了解决方案。 https://medium.com/@antonybudianto/react-router-testing-with-jest-and-enzyme-17294fefd303

我认为你需要像这样在“/”的路径之前加上

<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>

就像这意味着只有当你有这个 path="/" WeatherPage 显示你添加到它像 path="/impressum" 你将只看到 ImpressumPage。希望对你有帮助:)