Open5

ReactQueryを用いたhooksのテストを書きたい

堀川登喜矢堀川登喜矢

とりあえず下記2つの記事を見てmockWrapperを吐き出す関数を作った。
https://react-query.tanstack.com/guides/testing
https://tkdodo.eu/blog/testing-react-query

createMockProvider.tsx

import React, { ReactNode } from 'react';
import { QueryClient, QueryClientProvider } from 'react-query';

export const createMockProvider = () => {
  const queryClient = new QueryClient({
    defaultOptions: {
      queries: {
        // ✅ turns retries off
        retry: false,
      },
    },
  });

  const MockProvider = ({ children }: { children: ReactNode }) => (
    <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
  );

  return { MockProvider, queryClient };
};


堀川登喜矢堀川登喜矢

使うイメージはこんな感じ。

import { renderHook } from '@testing-library/react-hooks';
import { useUser } from './index';
import { createMockProvider } from './createMockProvider';

describe('useUser', () => {
  const id = 134;

  test('ユーザーが取得できる', async () => {
    const { MockProvider, queryClient } = createMockProvider();
    const { result, waitFor } = renderHook(() => useUser({ id }), {
      wrapper: MockProvider,
    });

    // userはまだ取れていない事を確認するための配置
    console.log(result.current.user?.name);

    await waitFor(() => !!result.current.user);
    expect(result.current.user).toBeTruthy();
  });

もちろんテスト失敗で怒られる。
今回はGraphQLを使っているのでProviderに食わせるものを用意する。

 FAIL  hooks/useUser/index.test.tsx (5.654 s)
  ● Console

    console.log
      undefined

      at hooks/useUser/index.test.tsx:13:13

  ● useUser › ユーザーとTODOが取得できる

    Timed out in waitFor after 1000ms.
堀川登喜矢堀川登喜矢

ひとまず、こんな感じにqueryClient.setQueryDataを使ってダミーデータを食わせてやりたい。

const { MockProvider, queryClient } = createMockProvider();
// 省略
await queryClient.setQueryData('user', mockUsers());
堀川登喜矢堀川登喜矢

GraphQLのmock dataを食わせる方法を検索中

  1. Apollo ClientみたいにMockProviderコンポーネントが有ればいいのに、見当たらない。
  2. nockというライブラリが有るみたい