路线不会根据 React 测试中的历史记录而改变

Pet*_*tru 5 reactjs react-router react-testing-library

尝试遵循来自https://testing-library.com/docs/example-react-router 的路由的测试示例,但 location.pathname/尽管历史上进行了推送,但仍然存在

import React from "react";
import { render, unmountComponentAtNode } from "react-dom";
import { act } from "react-dom/test-utils";
import { Router } from "react-router";
import { createMemoryHistory } from 'history'
import { prettyDOM } from '@testing-library/dom'

import App from '../../App.js'

let container = null;

beforeEach(() => {
  container = document.createElement("div");
  document.body.appendChild(container);
});

afterEach(() => {
  unmountComponentAtNode(container);
  container.remove();
  container = null;
});

test('Shows username in navbar after logging in', async () => {
  const fakeLoginResponse = {
    success: '1'
  };
  jest.spyOn(global, "fetch").mockImplementation(() =>
    Promise.resolve({
      json: () => Promise.resolve(fakeLoginResponse)
    })
  );

  const history = createMemoryHistory();
  history.push('/login');
  console.log(history);
  render(
    <Router history={history}>
      <App />
    </Router>,
    container
  );

  // console.log(prettyDOM(container));
  console.log(location.pathname); // prints /
  expect(container.querySelector("button").textContent).toBe('Log in'); // fails

  global.fetch.mockRestore();
});
Run Code Online (Sandbox Code Playgroud)

这是 App.js

import {
  BrowserRouter as Router,
  Link,
  Route,
  Switch,
  useHistory
} from "react-router-dom";
import { useTranslation } from 'react-i18next';
import { Layout } from 'antd';

import React, { useState } from 'react';
import './App.css';

import Auth from './Permissions/Auth.js';
import CreateCode from './Code/Create.js';
import Login from './User/Login';
import LoggedInRoute from './Permissions/LoggedInRoute.js';
import Navbar from './UI/Navbar.js';
import Register from './User/Register';

function App() {
  const { t } = useTranslation();
  const { Header, Content, Footer } = Layout;
  const [userData, setUserData] = useState({});

  function onLoginSuccess(id) {
    setUserData({ id: id });
  }

  return (
    <Layout className="layout">
      <Navbar userData={userData} />
      <Content>
        <Router>
          <nav>
            <ul>
              <li>
                <Link to="/">{t('welcome')}</Link>
              </li>
              <li>
                <Link to="/about">{t('About')}</Link>
              </li>
              <li>
                <Link to="/users">{t('Users')}</Link>
              </li>
              <li>
                <Link to="/register">{t('Register')}</Link>
              </li>
              <li>
                <Link to="/login">{t('Log in')}</Link>
              </li>
              <li>
                <Link to="/create-code">{t('Create code')}</Link>
              </li>
            </ul>
          </nav>

          {/* A <Switch> looks through its children <Route>s and
              renders the first one that matches the current URL. */}
          <Switch>
            <Route path="/about">
              <About />
            </Route>
            <Route path="/login">
              <Login onLoginSuccess={onLoginSuccess}/>
            </Route>
            <Route path="/register">
              <Register />
            </Route>
            <Route path="/users">
              <Users />
            </Route>
            <LoggedInRoute userData={userData} path="/create-code">
              <CreateCode />
            </LoggedInRoute>
            <Route path="/">
              <Home />
            </Route>
          </Switch>
        </Router>
      </Content>
    </Layout>
  );
}

function Home() {
  return <h2>Home</h2>;
}

function About() {
  return <h1>About</h1>;
}

function Users() {
  return <h3>Users</h3>;
}

export default App;
Run Code Online (Sandbox Code Playgroud)

Flo*_*Flo 0

我将这样做:

describe('<Component />', () => {
    let history: any;
    let rtl: RenderResult;

    beforeEach(() => {
        history = createMemoryHistory();
        history.push = jest.fn();

        rtl = render(
            <Router history={history}>
                <Component />
            </Router>
        );
    });

    test('routing', () => {
        // do something that triggers route change to '/url'
        // ...

        expect(history.push.mock.calls[0]).toEqual(['url']);
    });
});
Run Code Online (Sandbox Code Playgroud)

所以基本上,模拟推送方法能够期望其调用参数。

  • 我不是在测试推送。我希望根据路线呈现正确的组件。然而 / 被渲染 (3认同)