【问题标题】:Testing navigation with react-testing-library使用 react-testing-library 测试导航
【发布时间】:2022-02-07 17:00:57
【问题描述】:

我想测试我为导航创建的侧边栏是否有效,这是我所做的一个简单示例

<ul>
  <li><Link to="/location1">location 1</Link></li>
  <li><Link to="/location2">location 2</Link></li>
</ul>

这是我的测试

const routerWrapper = ({children}) => <BrowserRouter>{children}</BrowserRouter>

// The first one runs fine
it('navigation to location 1' , () => {
render(<SideBar/> , {wrapper:routerWrapper})
// get the element and click on it
// check if title of page is correct
})

it('navigation to location 2' , () => {
render(<SideBar/> , {wrapper:routerWrapper})
// can't run because location is at /location1
})

当我使用 RTL 测试导航时,第一次测试运行良好,但之后位置仍保留在该目录中以进行下一次测试,如何在每次测试后清除位置?或任何建议我应该如何测试导航?

【问题讨论】:

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


    【解决方案1】:

    来自Checking location in tests 文档:

    1. 如果您的测试环境具有浏览器全局变量 window.locationwindow.history(这是 Jest through JSDOM 中的默认设置,但您无法重置测试之间的历史记录),您也可以使用 BrowserRouter。
    1. 您可以将基础路由器与历史包中的历史道具一起使用,而不是将自定义路由传递给 MemoryRouter

    例如

    index.tsx:

    import React from 'react';
    import { Link } from 'react-router-dom';
    
    export function SideBar() {
      return (
        <ul>
          <li>
            <Link to="/location1">location 1</Link>
          </li>
          <li>
            <Link to="/location2">location 2</Link>
          </li>
        </ul>
      );
    }
    

    index.test.tsx:

    import { fireEvent, render, screen } from '@testing-library/react';
    import React from 'react';
    import { createMemoryHistory } from 'history';
    import { SideBar } from './';
    import { Router } from 'react-router';
    
    const createRouterWrapper = (history): React.ComponentType => ({ children }) => (
      <Router history={history}>{children}</Router>
    );
    
    describe('SideBar', () => {
      it('navigation to location 1', () => {
        const history = createMemoryHistory();
        render(<SideBar />, { wrapper: createRouterWrapper(history) });
        fireEvent.click(screen.getByText('location 1'));
        expect(history.location.pathname).toBe('/location1');
      });
    
      it('navigation to location 2', () => {
        const history = createMemoryHistory();
        render(<SideBar />, { wrapper: createRouterWrapper(history) });
        fireEvent.click(screen.getByText('location 2'));
        expect(history.location.pathname).toBe('/location2');
      });
    });
    

    测试结果:

     PASS  stackoverflow/70974339/index.test.tsx (8.701 s)
      SideBar
        ✓ navigation to location 1 (40 ms)
        ✓ navigation to location 2 (4 ms)
    
    -----------|---------|----------|---------|---------|-------------------
    File       | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
    -----------|---------|----------|---------|---------|-------------------
    All files  |     100 |      100 |     100 |     100 |                   
     index.tsx |     100 |      100 |     100 |     100 |                   
    -----------|---------|----------|---------|---------|-------------------
    Test Suites: 1 passed, 1 total
    Tests:       2 passed, 2 total
    Snapshots:   0 total
    Time:        9.232 s
    

    【讨论】:

    • 其实当我问这个的时候我并不知道,我最终使用了那个。但这似乎也是一个好方法。谢谢
    【解决方案2】:

    好吧,我确实想通了,我们可以为此使用&lt;MemoryRouter&gt;https://reactrouter.com/docs/en/v6/api#memoryrouter

    刚刚将值 ['/'] 从 &lt;MemoryRouter&gt; 传递给 initialEntries 属性,测试工作正常。

    还有slideshowp2 answer 如果您有兴趣,非常有用

    【讨论】:

    • 是的。 MemoryRouter 是另一种方式。
    • 但是/是默认值,它还没有导航。
    猜你喜欢
    • 2019-05-21
    • 2019-11-11
    • 2023-04-04
    • 1970-01-01
    • 2019-08-29
    • 2021-11-30
    • 2019-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多