web-dev-qa-db-ja.com

React-Hooks-Testing-Libraryを使用したカスタム非同期/ Awaitフックをテストする方法

私は、REDUXの状態に保存したくないすべての重要なAPI要求を処理することを想定しているカスタムReact Hookを作成しました。フックは元気ですが、テストに問題があります。私のテスト設定はjestと酵素ですが、私は試してみることにしました React-Hooks-testing-libraryここでも.

私が今まで試したことは、最初の模擬フェッチ要求をFetch-Mockライブラリー、正常に動作します。次に、React-Hooks-Testing-Libraryから来るrenderHookメソッドでフックをレンダリングします。残念ながら、waitForNextUpdateメソッドを全く理解していないようです。

これが私のフックのように見える方法です。

seapiフック

export function useApi<R, B = undefined>(
    path: string,
    body: B | undefined = undefined,
    method: HttpMethod = HttpMethod.GET
): ResponseStatus<R> {
    const [response, setResponse] = useState();
    const [isLoading, setIsLoading] = useState<boolean>(false);
    const [error, setError] = useState<string | boolean>(false);

    useEffect(() => {
        const fetchData = async (): Promise<void> => {
            setError(false);
            setIsLoading(true);
            try {
                const result = await callApi(method, path, body);
                setResponse(result);
            } catch (errorResponse) {
                setError(errorResponse);
            }

            setIsLoading(false);
        };

        fetchData();
    }, [path, body, method]);

    return { response, isLoading, error };
}
 _

フックは、テストしたい3つの異なる状態の組み合わせを取ります。残念ながら、どうやってわかりません。

データのロード:

{ response: undefined, isLoading: true, error: false }
 _

ロードされたデータ:

{ response: R, isLoading: false, error: false }
 _

エラー:

{ response: undefined, isLoading: false, error: true }
 _

これは私のテストがこの瞬間のように見える方法です。

import fetchMock from 'fetch-mock';
import { useApi } from './hooks';
import { renderHook } from '@testing-library/react-hooks';

test('', async () => {
    fetchMock.mock('*', {
        returnedData: 'foo'
    });

    const { result, waitForNextUpdate } = renderHook(() => useApi('/data-owners'));

    console.log(result.current);

    await waitForNextUpdate();

    console.log(result.current);
});
 _

callapi func

/**
 * Method to call api.
 *
 * @param {HttpMethod} method - Request type.
 * @param {string} path - Restful endpoint route.
 * @param {any} body - Request body data.
 */
export const callApi = async (method: HttpMethod, path: string, body: any = null) => {
    // Sends api request
    const response = await sendRequest(method, path, body);
    // Checks response and parse to the object
    const resJson = response ? await response.json() : '';

    if (resJson.error) {
        // If message contains error, it will throw new Error with code passed in status property (e.g. 401)
        throw new Error(resJson.status);
    } else {
        // Else returns response
        return resJson;
    }
};
 _
19
Dan Zawadzki

あなたがしたことは大丈夫です。さて、あなたはテストに期待される使用が必要です。

const value = {...}
expect(result.current).toEqual(value)
 _
1
Leandro Budau