これを2つの異なるコードベースで確認しましたが、実際のブラウザーでは正常に機能しますが、テストでは機能しないため困惑しています。コンポーネントがuseParams
フックを使用すると、フックはテストでエラーをスローします。
エラー:キャッチされません[TypeError: 'undefined'または 'null'のプロパティ
accountId
を分解できません。]
私はReact Functional Component、React Testing Library and 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場所:{パス名: '/ 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 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から、状態の変化を正しく解決させるテストでawait
を使用するようにしています。
ルートパラメータを正しく取得していないReact-Routerフックについてはどうですか?
推奨されるようなルーター/ルートのラッパーがある場合でも、テストするコンポーネントがパラメーター付きのルートでラップされることを確認してください。
<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.com/a/58180976/2295549 を参照してください。