質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
Next.js

Next.jsは、Reactを用いたサーバサイドレンダリングなどを行う軽量なフレームワークです。Zeit社が開発しており、nextコマンドでプロジェクトを作成することにより、開発環境整備が整った環境が即時に作成できます。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

0回答

2506閲覧

[Recoil][Nextjs]useRouterを含むカスタムフックのテスト

sabx

総合スコア200

Next.js

Next.jsは、Reactを用いたサーバサイドレンダリングなどを行う軽量なフレームワークです。Zeit社が開発しており、nextコマンドでプロジェクトを作成することにより、開発環境整備が整った環境が即時に作成できます。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2020/12/31 10:39

編集2020/12/31 10:39

聞きたいこと

Nextjs + Recoil でWebアプリを作成しています。
独自で作成したカスタムフックををJestでテストしようと思っているのですが、そのカスタムフック内でuseRouterを使用しているため、下のエラーが発生してしまいます。

unit test for custom hook useIds TypeError: Cannot read property 'query' of null 17 | const [ids, setIds] = useRecoilState(idsState); 18 | const router = useRouter(); > 19 | const { type } = router.query;

実際に実行したテストコードはこちらです。

import * as React from 'react'; import { act, renderRecoilHook } from 'react-recoil-hooks-testing-library'; import { useIds } from '@/hooks'; import { withMockedRouter, MockedRouter } from '@/utils/mock'; it('custom hook test', () => { const { result } = renderRecoilHook(() => useIds()); act(() => { console.log(result.current.ids); }) })

またテスト対象のカスタムフックはこちらです。

import * as React from 'react'; import { useRouter } from 'next/router'; import { atom, useRecoilState } from 'recoil'; import { fetchIdsByType } from '@/repositories'; const initialState: { [type: string]: number[]; } = {}; export const idsState = atom({ key: 'idsState', default: initialState, }); const useIds = () => { const [ids, setIds] = useRecoilState(idsState); const router = useRouter(); const { type } = router.query; React.useEffect(() => { if (router.asPath !== router.route) { // @ts-ignore fetchIdsByType(type).then((ids: number[]) => { setIds((prevState) => { return { ...prevState, // @ts-ignore [type]: ids, }; }); }); } }, [router]); // @ts-ignore return ids[type]; }; export { useIds };

試してみたこと

上のテストコード内で実行されている renderRecoilHook の第2引数に、NextjsのRoutingに関するコンポーネントをWrapperとして渡せば良さそうだと思い、下のような実装を試してみました。

import * as React from 'react'; import { act, renderRecoilHook } from 'react-recoil-hooks-testing-library'; import { useIds } from '@/hooks'; import { withMockedRouter, MockedRouter } from '@/utils/mock'; it('custom hook test', () => { const wrapper = (children) => <MockedRouter>{children}</MockedRouter>; const { result } = renderRecoilHook(() => useIds(), { wrapper }); act(() => { console.log(result.current.ids); }) const { result } = renderHook(() => useCount()); act(() => { result.current.increment(); }); })
  • MockRouter
import React from "react"; import { NextRouter } from 'next/router'; import { RouterContext } from 'next/dist/next-server/lib/router-context'; export const MockedRouter = (router: Partial<NextRouter> = {}, children: React.ReactElement) => { const mockedRouter = { route: '', pathname: '', query: {}, asPath: '', push: async () => true, replace: async () => true, reload: () => null, back: () => null, prefetch: async () => undefined, beforePopState: () => null, events: { on: () => null, off: () => null, emit: () => null, }, }; // @ts-ignore return <RouterContext.Provider value={mockedRouter}>{ children }</RouterContext.Provider>; };

試してみた結果、下のようなエラーが表示されてしまいました。

custom hook test Objects are not valid as a React child (found: object with keys {}). If you meant to render a collection of children, use an array instead. 8 | it('custom hook test', () => { 9 | const wrapper = (children) => <MockedRouter>{children}</MockedRouter>; > 10 | const { result } = renderRecoilHook(() => useIds(), { wrapper });

ここまで試してみましたが、自力解決が難しかったので、どなたか解決の糸口を教えてほしいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問