如何使用酶为 React Router 的 URL 参数创建单元测试

cos*_*oll 8 unit-testing reactjs jestjs react-router enzyme

我正在尝试使用 React Router 的 Enzyme 来测试 url 参数。到目前为止,该应用程序很简单。我有 App.jsx,它有<Router />一个<Switch />组件和两个<Route />组件。

任何帮助将设立一个试验取URL作为理解path<Route />,并在孩子的路径存根返回一个值<Files />组件。

我对测试完全陌生,所以请链接文档(如果有),并请伪代码或演示您的方法的概述,以便我可以将其放入适当的上下文中。

我还没有看到任何适合我的理解水平的用于测试 URL 参数功能的适当或上下文化的方法。这里有一个答案建议使用 Jest 进行嘲笑,How to test components using new react router hooks?但没有足够的上下文让我实施。

这是 create-react-app 的基本站立:

function App() {
  const [user] = useState(sampleUser);

  return (
    <UserContext.Provider value={user}>
      <SiteHeader />
      <Router>
        <Switch>
          <Route path="/files/:fileId">
            <Files />
          </Route>
          <Route path="*">
            <header className="App-header">
              <img src={logo} className="App-logo" alt="logo" />
              <p>
                Edit
                <code>src/App.js</code>
                and save to reload.
              </p>
              <a
                className="App-link"
                href="https://reactjs.org"
                target="_blank"
                rel="noopener noreferrer"
              >
                Learn React
              </a>
            </header>
          </Route>
        </Switch>
      </Router>
    </UserContext.Provider>
  );
}

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

我对单独测试<Files />和传入 URL感兴趣。从钩子上<Files />解构。fileIduseParams

Files 的组件如下所示:

import React from 'react';
// import PropTypes from 'prop-types';
import { useParams, Router } from 'react-router-dom';

const Files = () => {
  const { fileId } = useParams();
  return (
    <main>
      {`component for ${fileId}`}
    </main>
  );
};

Files.propTypes = {};

Files.defaultProps = {};

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

对于我的测试,我正在导入 Files 和 Route,因为 Filespath使用useParams钩子继承了Route 。我正在安装<Route path="/files/:fileId" component={Files} />,我正在包装它<MemoryRouter initialEntries={['/files/mockId']} initialIndex={0}>以获得状态。完整代码如下所示:

import React from 'react';
import { mount, shallow, configure, render } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import { MemoryRouter, matchPath, useParams } from 'react-router-dom';
import Files from './Files.jsx';
import Route from '../../App.jsx';

configure({ adapter: new Adapter() });

describe('FilesPage', () => {

  it('has fileId of `mockId`', () => {
    const wrapper = mount(
      <MemoryRouter initialEntries={['/page-tagger/mockId']} initialIndex={0}>
        <Route path="/page-tagger/:fileId" component={Files} />
        // <Files />
      </MemoryRouter>
    );

    // Get value fileId from <Files />
  });
});
Run Code Online (Sandbox Code Playgroud)

我尝试了许多不同的方法来从<Files />组件中获取任何价值,但都无济于事。我尝试了一个shallow(<Files />),但这会导致useParamsFiles.jsx 文档中未定义的错误。所以,我安装并使用了<MemoryRouter />. 当我看到 wrapper.props() 是什么样子时,我可以看到<Route />App 的 props().children 元素具有路径,并且钩子useParam不是道具或任何东西<Files />。中的 url<MemoryRouter />不会传递给孩子,<Route />也不会传递给<Files />.

Emm*_*fon 0

React Router 基于一个名为 的包history,用于处理与浏览器的所有交互。

您可以创建一个 Router 并向其传递一个历史记录实例以在测试期间管理 URL:

import {createMemoryHistory} from 'history';

test('', () => {
  const history = createMemoryHistory();
  mount(
    <Router history={history}>
      /* your components */
    </Router>
  )
})
Run Code Online (Sandbox Code Playgroud)