web-dev-qa-db-ja.com

テスト中にuseParamsがラッパー付きのテスト環境で未定義を返すのはなぜですか?

これを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フックについてはどうですか?

2
Phil Lucks

推奨されるようなルーター/ルートのラッパーがある場合でも、テストするコンポーネントがパラメーター付きのルートでラップされることを確認してください。

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

次のようにJestを使用してクエリパラメータをモックすることもできます。

describe(() => {
    test('...', () => {
        jest.spyOn(ReactRouter, 'useParams').mockReturnValue({ id: '1234' });
        // id = 1234 in your tested component
    });
});

反応ルーターのモックをさらに詳しく見るには https://stackoverflow.com/a/58180976/2295549 を参照してください。

0
Florian