我已经在2个不同的代码库中看到了这个问题,我很困惑,因为它在实际的浏览器中可以正常工作,但在测试中却不行:如果一个组件使用了 useParams
钩子,钩子在测试中抛出一个错误。
错误: 未捕获[TypeError: 类型错误:无法重构属性
accountId
的'undefined'或'null']。
我使用的是React Functional Component,React Testing Library和React-Router。
Router: / component:
const Overview: FC = () => {
const location = useLocation();
console.log(location) // see below
const { accountId } = useParams();
console.log(accountId) // see below
... rest
}
控制台日志似乎已经找到了正确的params。
console.log srcscreensOverviewindex.tsx:66 accountId: nodata。
console.log srcscreensOverviewindex.tsx:64位置。 { pathname: 'mixoverviewnodata', search: '', hash: '', state: undefined, key: 'bn6zvv' }。
/ 中推荐的带有包装器的测试设置。RTL文档
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 srctest-utilsindex.js: 19 route: mixoverviewnodata.
console.log srctest-utilsindex.js:20 params: mixoverview: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到使用 await
的测试中,让状态变化正确地进行结算。
React-Router钩子没有正确地拾取路由参数是怎么回事?
确保,即使你有一个像建议的RouterRoute的包装器,你想测试的组件也会被一个带params的Route包装。
<Route path="/mix/config/:param1/:param2/:param3" >
<Config />
</Route>
你也可以使用Jest模拟查询参数,就像这样。
describe(() => {
test('...', () => {
jest.spyOn(ReactRouter, 'useParams').mockReturnValue({ id: '1234' });
// id = 1234 in your tested component
});
});
参见 https:/stackoverflow.coma581809762295549。 来模拟更多的react-router。