为什么在测试过程中使用包装器在测试环境中未使用useParams返回未定义?

时间:2020-04-30 23:01:35

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

我现在已经在2个不同的代码库中看到了这一点,并且感到困惑,因为它在实际的浏览器中可以正常工作,但在测试中却不能:如果组件使用useParams钩子,则该钩子会在测试中引发错误:

错误:未捕获[TypeError:无法解构'undefined'或'null'的属性accountId。]

我正在使用React功能组件,React测试库和React-Router:

//组件:

const Overview: FC = () => {
  const location = useLocation();
  console.log(location) // see below
  const { accountId } = useParams();
  console.log(accountId) // see below

  ... rest
}

控制台日志似乎已正确找到参数:

console.log src / screens / Overview / index.tsx:66 accountId:无数据

console.log src / screens / Overview / index.tsx:64 位置:{路径名:“ / mix / overview / nodata”, 搜索:“, 哈希:“, 状态:未定义, 密钥:“ bn6zvv”}

//根据RTL docs

的建议使用包装器测试设置

function renderWithProviders(
  ui,
  {
    route = '/',
    params = routes.root, 
    history = createMemoryHistory({ initialEntries: [route] }),
  } = {},
  apolloMocks
) {
  console.log("route:", route) // see below
  console.log("params:", params) // see below
  return {
    ...render(
      <Provider store={mockProviderStore}>
        <Router history={history}>
          <MockedProvider mocks={apolloMocks}>
            <Route path={params}> // tried to set path to "params" not "route" so the slug of /url/:accountId is properly set
             {ui}
            </Route>
          </MockedProvider>
        </Router>
      </Provider>
    ),
    history,
  };
}

test-utils文件中的控制台日志结果看起来正确:

console.log src / test-utils / index.js:19 路线:/ mix / overview / nodata

console.log src / test-utils / index.js:20 参数:/ mix / overview /:accountId

//自我测试

test('it works', async () => {
    const { findByText } = renderWithProviders(<Overview />, {
      route: routes.overview('1234567890'), // => path/1234567890
      params: routes.overview(), // => path/:accountId
    });

    await findByText('loading configs...');

    await waitForElementToBeRemoved(() => getByText('loading configs...'));

    await findByText('View your stuff now. It works!');
  });

我正在尝试#kentdodds的recommended work around在测试中使用await,以使状态更改能够正确解决。

React-Router钩有什么用,它不能正确地拾取路由参数?

2 个答案:

答案 0 :(得分:1)

即使使用建议的路由器/路由包装,也要确保要测试的组件被带参数的Route包裹:

<Route path="/mix/config/:param1/:param2/:param3" >
        <Config />
      </Route>

答案 1 :(得分:1)

您还可以像这样使用Jest模拟查询参数:

attackMonster

请参见https://stackoverflow.com/a/58180976/2295549以模拟更多的react-router。