无法让 MemoryRouter 与@testing-library/react 一起工作

Can't get MemoryRouter to work with @testing-library/react

我正在尝试测试我的路由器是否按预期工作。但是我无法让路由器指向 /

以外的其他位置

这是我的简化测试代码。

App.tsx

import React from 'react';
import {Route, Switch, BrowserRouter} from 'react-router-dom';

const App: React.FC = () => {
    return (
        <div>
            <BrowserRouter>
                <Switch>
                    <Route path={'/test'}>test</Route>
                    <Route path={'/'}>index</Route>
                </Switch>
            </BrowserRouter>
        </div>
    );
};

export default App;

App.test.tsx

import React from 'react';
import App from './App';
import {MemoryRouter} from 'react-router-dom';
import {render} from '@testing-library/react';


test('renders /test route', async () => {
    const app = render(
        <MemoryRouter initialEntries={['/test']} initialIndex={0}>
            <App/>
        </MemoryRouter>);
    expect(app.getByText(/test/i)).toBeInTheDocument();
});

我收到以下错误消息

Error: Unable to find an element with the text: /test/i. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

<body>
  <div>
    <div>
       index
    </div>
  </div>
</body>

我做错了什么?

问题是,我要测试的组件已经声明了路由器。 为了解决这个问题,我不得不将 App 组件拆分为 AppRoutes

为了测试,我只需要渲染 Routes 组件,一切都按预期进行。

App.tsx

import React from 'react';
import {Route, Switch, BrowserRouter} from 'react-router-dom';

export const Routes = () => {
    return (
        <>
            <Switch>
                <Route path={'/test'}> test</Route>
                <Route path={'/'}> index</Route>
            </Switch>
        </>
    )
};

const App: React.FC = () => {
    return (
        <div>
            <BrowserRouter>
                <Routes/>
            </BrowserRouter>
        </div>
    );
};

export default App;

App.test.tsx

import React from 'react';
import {Routes} from './App';
import {MemoryRouter} from 'react-router-dom';
import {render} from '@testing-library/react';


test('renders routes correct', async () => {
    const app = render(
        <MemoryRouter initialEntries={['/test']} initialIndex={0}>
            <Routes/>
        </MemoryRouter>
    );
    expect(app.getByText(/test/i)).toBeInTheDocument();
});

如果你从 index.js 加载 App,当我 运行 在 Create React App 应用程序上遇到这个问题时就是这种情况,你也可以包装 AppRouter 中,然后按照您的预期测试 App 路由,而不必像您所做的那样导出 Routes

例如(否则股票 CRA index.js):

// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router } from 'react-router-dom';
import './index.css';
import App from './app';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(
  <React.StrictMode>
    <Router>
      <App />
    </Router>
  </React.StrictMode>,
  document.getElementById('root')
);

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
serviceWorker.unregister();