如何使用 react-hooks-testing-library 测试自定义 async/await 钩子
Posted
技术标签:
【中文标题】如何使用 react-hooks-testing-library 测试自定义 async/await 钩子【英文标题】:How to test custom async/await hook with react-hooks-testing-library 【发布时间】:2019-12-21 01:51:45 【问题描述】:我创建了一个自定义反应钩子,它应该处理所有不太重要的 api 请求,我不想将其存储在 redux 状态。 Hook 工作正常,但我无法测试它。我的测试设置是 jest 和酵素,但我决定在这里也试试 react-hooks-testing-library。
到目前为止,我尝试的是首先使用 fetch-mock 库模拟 fetch 请求,效果很好。接下来,我使用来自 react-hooks-testing-library 的 renderHook
方法渲染钩子。不幸的是,看起来我不太了解waitForNextUpdate
方法。
这就是我的钩子的样子。
使用Api挂钩
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 种不同的状态组合。不幸的是,我不知道怎么做。
加载数据:
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 函数
/**
* 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;
;
【问题讨论】:
react-hooks-testing-library
作者在这里。您对renderHook
和waitForNextUpdate
的使用看起来是正确的,所以我认为要么发生批处理问题,要么存在阻止更新发生的其他原因。测试失败时以及从控制台日志中看到的实际错误是什么?
【参考方案1】:
你做的很好。现在,您需要使用 expect 进行测试。
const value = ...
expect(result.current).toEqual(value)
【讨论】:
以上是关于如何使用 react-hooks-testing-library 测试自定义 async/await 钩子的主要内容,如果未能解决你的问题,请参考以下文章
如何在自动布局中使用约束标识符以及如何使用标识符更改约束? [迅速]
如何使用 AngularJS 的 ng-model 创建一个数组以及如何使用 jquery 提交?