美文网首页
Guide-2019-05-13-React Router 4.

Guide-2019-05-13-React Router 4.

作者: 自律财富自由 | 来源:发表于2019-05-13 11:45 被阅读0次

    React Router依赖React上下文来工作。这会影响您如何进行测试组件。

    上下文

    如果您尝试单元测试一个呈现<Link>或<Route>等的组件,您将收到一些有关上下文的错误和警告。虽然您可能想要自己删除路由器上下文,但我们建议您将单元测试包装在<StaticRouter>或<MemoryRouter>中。

    class Sidebar extends Component {
      // ...
      render() {
        return (
          <div>
            <button onClick={this.toggleExpand}>expand</button>
            <ul>
              {users.map(user => (
                <li>
                  <Link to={user.path}>{user.name}</Link>
                </li>
              ))}
            </ul>
          </div>
        );
      }
    }
    
    // broken
    test("it expands when the button is clicked", () => {
      render(<Sidebar />);
      click(theButton);
      expect(theThingToBeOpen);
    });
    
    // fixed!
    test("it expands when the button is clicked", () => {
      render(
        <MemoryRouter>
          <Sidebar />
        </MemoryRouter>
      );
      click(theButton);
      expect(theThingToBeOpen);
    });
    

    从特定路由开始

    <MemoryRouter> 支持initialEntries以及initialIndex属性。这样您就可以在特定位置(或应用程序的任何较小部分)启动应用程序。

    import { render, unmountComponentAtNode } from "react-dom";
    import React from "react";
    import { Route, Link, MemoryRouter } from "react-router-dom";
    import { Simulate } from "react-addons-test-utils";
    
    // a way to render any part of your app inside a MemoryRouter
    // you pass it a list of steps to execute when the location
    // changes, it will call back to you with stuff like
    // `match` and `location`, and `history` so you can control
    // the flow and make assertions.
    const renderTestSequence = ({
      initialEntries,
      initialIndex,
      subject: Subject,
      steps
    }) => {
      const div = document.createElement("div");
    
      class Assert extends React.Component {
        componentDidMount() {
          this.assert();
        }
    
        componentDidUpdate() {
          this.assert();
        }
    
        assert() {
          const nextStep = steps.shift();
          if (nextStep) {
            nextStep({ ...this.props, div });
          } else {
            unmountComponentAtNode(div);
          }
        }
    
        render() {
          return this.props.children;
        }
      }
    
      class Test extends React.Component {
        render() {
          return (
            <MemoryRouter
              initialIndex={initialIndex}
              initialEntries={initialEntries}
            >
              <Route
                render={props => (
                  <Assert {...props}>
                    <Subject />
                  </Assert>
                )}
              />
            </MemoryRouter>
          );
        }
      }
    
      render(<Test />, div);
    };
    
    // our Subject, the App, but you can test any sub
    // section of your app too
    const App = () => (
      <div>
        <Route
          exact
          path="/"
          render={() => (
            <div>
              <h1>Welcome</h1>
            </div>
          )}
        />
        <Route
          path="/dashboard"
          render={() => (
            <div>
              <h1>Dashboard</h1>
              <Link to="/" id="click-me">
                Home
              </Link>
            </div>
          )}
        />
      </div>
    );
    
    // the actual test!
    it("navigates around", done => {
      renderTestSequence({
        // tell it the subject you're testing
        subject: App,
    
        // and the steps to execute each time the location changes
        steps: [
          // initial render
          ({ history, div }) => {
            // assert the screen says what we think it should
            console.assert(div.innerHTML.match(/Welcome/));
    
            // now we can imperatively navigate as the test
            history.push("/dashboard");
          },
    
          // second render from new location
          ({ div }) => {
            console.assert(div.innerHTML.match(/Dashboard/));
    
            // or we can simulate clicks on Links instead of
            // using history.push
            Simulate.click(div.querySelector("#click-me"), {
              button: 0
            });
          },
    
          // final render
          ({ location }) => {
            console.assert(location.pathname === "/");
            // you'll want something like `done()` so your test
            // fails if you never make it here.
            done();
          }
        ]
      });
    });
    

    相关文章

      网友评论

          本文标题:Guide-2019-05-13-React Router 4.

          本文链接:https://www.haomeiwen.com/subject/wsklaqtx.html