为什么 useParams during test return undefined in test env with wrapper?
Why does useParams during test return undefined in test env with wrapper?
我现在已经在 2 个不同的代码库中看到了这个,我很困惑,因为它在实际的浏览器中工作正常,但在测试中却不行:如果一个组件使用 useParams
钩子,钩子会在测试:
Error: Uncaught [TypeError: Cannot destructure property accountId
of 'undefined' or 'null'.]
我正在使用 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: nodata
console.log src/screens/Overview/index.tsx:64
location: { pathname: '/mix/overview/nodata',
search: '',
hash: '',
state: undefined,
key: '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
route: /mix/overview/nodata
console.log src/test-utils/index.js:20
params: /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 钩子是怎么回事?
确保,即使你有一个像建议的 Router/Route 的包装器,你要测试的组件也会被一个带有参数的路由包装:
<Route path="/mix/config/:param1/:param2/:param3" >
<Config />
</Route>
您也可以像这样使用 Jest 模拟查询参数:
import ReactRouter from 'react-router'
describe(() => {
test('...', () => {
jest.spyOn(ReactRouter, 'useParams').mockReturnValue({ id: '1234' });
// id = "1234" in your tested component
});
});
请参阅 以模拟更多 react-router。
我现在已经在 2 个不同的代码库中看到了这个,我很困惑,因为它在实际的浏览器中工作正常,但在测试中却不行:如果一个组件使用 useParams
钩子,钩子会在测试:
Error: Uncaught [TypeError: Cannot destructure property
accountId
of 'undefined' or 'null'.]
我正在使用 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: nodata
console.log src/screens/Overview/index.tsx:64 location: { pathname: '/mix/overview/nodata', search: '', hash: '', state: undefined, key: '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 route: /mix/overview/nodata
console.log src/test-utils/index.js:20 params: /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 钩子是怎么回事?
确保,即使你有一个像建议的 Router/Route 的包装器,你要测试的组件也会被一个带有参数的路由包装:
<Route path="/mix/config/:param1/:param2/:param3" >
<Config />
</Route>
您也可以像这样使用 Jest 模拟查询参数:
import ReactRouter from 'react-router'
describe(() => {
test('...', () => {
jest.spyOn(ReactRouter, 'useParams').mockReturnValue({ id: '1234' });
// id = "1234" in your tested component
});
});
请参阅