【问题标题】:Can't get MemoryRouter to work with @testing-library/react无法让 MemoryRouter 与 @testing-library/react 一起使用
【发布时间】:2020-01-24 07:45:13
【问题描述】:

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

这是我的简化测试代码。

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>

我做错了什么?

【问题讨论】:

    标签: reactjs react-router react-testing-library


    【解决方案1】:

    问题是,我想测试的组件已经声明了一个路由器。 为了解决这个问题,我不得不将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();
    });
    
    

    【讨论】:

    • 这太难了!我希望将这样的示例添加到 React-testing-library 文档或 React-Router 文档中。或两者! ?
    • 它是开源的。你为什么不添加它,@DavidTorres
    【解决方案2】:

    如果您从index.js 加载App,当我在 Create React App 应用程序上遇到此问题时就是这种情况,您也可以将App 包装在Router 中然后测试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();
    

    【讨论】:

      猜你喜欢
      • 2019-02-01
      • 1970-01-01
      • 2019-10-17
      • 1970-01-01
      • 2020-02-27
      • 2019-07-07
      • 2019-05-21
      • 2019-11-11
      • 2021-06-02
      相关资源
      最近更新 更多