使用 react-testing-library 测试导航

Testing navigation with react-testing-library

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

<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 测试导航时,第一次测试运行正常,但之后位置保留在该目录以供下一次测试,如何在每次测试后清除位置?或者我应该如何测试导航的任何建议?

来自 Checking location in tests 文档:

  1. You can also use BrowserRouter if your test environment has the browser globals window.location and window.history (which is the default in Jest through JSDOM, but you cannot reset the history between tests).
  1. Instead of passing a custom route to MemoryRouter, you can use the base Router with a history prop from the history package

例如

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  Whosebug/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

好吧,我确实弄明白了,我们可以使用 <MemoryRouter> 来达到这个目的。 https://reactrouter.com/docs/en/v6/api#memoryrouter

刚刚将值 ['/'] 传递给 <MemoryRouter> 中的 initialEntries 属性,测试工作正常。

还有 有兴趣的话很有用