我无法在测试中设置specefic路径

时间:2017-03-28 17:40:58

标签: testing react-router jestjs

问题:我的应用组件负责根据路径呈现其他组件。所以为了测试它,我需要能够“设置”路径。例如,当路径为 / sign-up 时,我想看到SignUp组件被渲染。

我做了什么:我以为我可以使用initialEntries为MemoryRouter提供一条初始路径(不成功)然后我想我可以直接在MemoryRouter里面的测试中使用Route / Redirect设置路径,但这也不起作用。

规格:

  • React 15
  • React Router 4(react-router-dom)
  • Redux 3.6
  • Jest(一个带有create-react-app的人)
  • Yo可以在branch with the issue
  • 上找到代码

2 个答案:

答案 0 :(得分:2)

我花了一段时间试图弄明白自己。 简单地说,你不能在<Router>内嵌套<MemoryRouter>,因为它们都是路由器。

解决方案示例:

Routes.js - 从中移除<BrowserRouter>,以便您测试代码。

    import React from 'react';
    import { Route, Switch } from 'react-router-dom';
    import SignUp from '../SignUp/SignUp'; //your signup component
    import Home from '../Home/Home'; //some other component for an example

    const MyRoutes = () => (
        <Switch>
            <Route path="/" component={Home} />
            <Route path="/signup" component={SignUp} />
        </Switch>
    );

    export default MyRoutes;

index.js - 在此处添加<BrowserRouter>,因为您需要将<Switch>包裹在<Router>中。

    import React from 'react';
    import ReactDOM from 'react-dom';
    import { BrowserRouter } from 'react-router-dom';
    import Routes from './Components/Routes/Routes';

    ReactDOM.render(
      (
        <BrowserRouter>
          <Routes />
        </BrowserRouter>
      ), document.getElementById('root')
    );

tests / Routes.test.js - 现在在此处添加<MemoryRouter>进行测试。

    import React from 'react';
    import ReactDOM from 'react-dom';
    import { MemoryRouter } from 'react-router-dom';
    import Routes from '../Components/Routes/Routes';

    const TestRoute = props => (
      <MemoryRouter initialEntries={props.initialEntries}>
          <Routes {...props} />
      </MemoryRouter>
    );

    it('at /signup it displays the signup page', () => {
      const div = document.createElement('div');
      ReactDOM.render(<TestRoute initialEntries={['/signup']} />, div); // render on the route "/signup"
      const elem = div.getElementsByClassName('signup')[0];
      expect(elem).not.toBe(undefined); // check an element exists with that class
      if(elem !== undefined) {
        expect(elem.innerHTML).toEqual('signup'); // check it has worked
      }
    });

换句话说,您将路由/交换机与路由器分开以使您能够对其进行测试,因为您无法嵌套两个路由器。

答案 1 :(得分:0)

我遇到了类似的问题,我发现以下内容适用于测试其行为根据路线而变化的组件:

<MemoryRouter initialEntries={['/about']}>
  <Navigation {...props} />
</MemoryRouter>

在此实例中,快照显示.active className已添加到Navigation中的“about”链接。

似乎没有用的是在包含初始路由的组件/容器周围添加内存路由器。为了简单起见,我将基本路由页面缩减为:

<Router>
  <div className="App">
    <Navigation app={this.props.app} />
    <Switch>
      <Route exact path="/" component={Home} />
      <Route exact path="/about" component={About} />
      <Route exact path="/login" render={() => <Login app={this.props.app} />} />
      <Route exact path="/signup" render={() => <Signup app={this.props.app} />} />
      <Route exact path="/account" render={() => <Account app={this.props.app} />} />
      <Route component={ErrorPage} />
    </Switch>
  </div>
</Router>

react-router团队在current testing docs中声明:

  

我们有很多测试,当位置发生变化时,路线会起作用,   所以你可能不需要测试这些东西。