我现在已经在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钩有什么用,它不能正确地拾取路由参数?
答案 0 :(得分:1)
即使使用建议的路由器/路由包装,也要确保要测试的组件被带参数的Route包裹:
<Route path="/mix/config/:param1/:param2/:param3" >
<Config />
</Route>
答案 1 :(得分:1)
您还可以像这样使用Jest模拟查询参数:
attackMonster
请参见https://stackoverflow.com/a/58180976/2295549以模拟更多的react-router。