问题描述
我创建了一个自定义的 react 钩子,它应该处理所有不太重要的 api 请求,我不想将这些请求存储在 redux 状态中.Hook 工作正常,但我无法测试它.我的测试设置是开玩笑和酶,但我决定在这里尝试一下react-hooks-testing-library.
I created a custom react hook that is supposed to handle all less important api requests, which i don't want to store in the redux state. Hook works fine but I have trouble testing it. My test setup is jest and enzyme, but I decided to give a try react-hooks-testing-library here as well.
到目前为止我所尝试的是首先使用 fetch-mock 库模拟 fetch 请求,效果很好.接下来,我使用来自 react-hooks-testing-library 的 renderHook
方法渲染钩子.不幸的是,我似乎不太了解 waitForNextUpdate
方法.
What I have tried so far is to first mock fetch request with a fetch-mock library, what works fine. Next, i render hook with renderHook
method, which comes from react-hooks-testing-library. Unfortunately, looks like I do not quite understand the waitForNextUpdate
method.
这就是我的钩子的样子.
This is how my hook looks like.
useApi 钩子
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 };
}
Hook 可以采用我想要测试的 3 种不同状态组合.不幸的是,我不知道如何.
Hook can take 3 different state combinations that I would like to test. Unfortunately, I have no idea how.
加载数据:
{ response: undefined, isLoading: true, error: false }
加载的数据:
{ response: R, isLoading: false, error: false }
错误:
{ response: undefined, isLoading: false, error: true }
这就是我现在测试的样子:
This is how my test looks like at this moment:
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 函数
/**
* 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;
}
};
推荐答案
你做的很好.现在,您需要使用 expect 进行测试.
It's all right that you did. Now, you need use expect for test.
const value = {...}
expect(result.current).toEqual(value)
这篇关于如何使用 react-hooks-testing-library 测试自定义异步/等待钩子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!