在 useEffect 挂钩中进行的异步调用的测试结果
Posted
技术标签:
【中文标题】在 useEffect 挂钩中进行的异步调用的测试结果【英文标题】:Testing results for async calls made in useEffect hook 【发布时间】:2019-12-24 06:35:21 【问题描述】:我试图断言我的自定义挂钩在挂载时会从 API 返回一些数据。
代码如下:
import * as React from 'react';
import findByStatus from '../../services/AssignmentService';
import Assignment from '../../models/Assignment';
import AssignmentList from './AssignmentList';
type AssignmentListApiHookTuple = [Assignment[], React.Dispatch<React.SetStateAction<string>>];
export const useAssignmentListApi = (initialStatus: string = ''): AssignmentListApiHookTuple =>
const [assignments, setAssignments] = React.useState<Assignment[]>([]);
const [status, setStatus] = React.useState<string>(initialStatus);
React.useEffect(
() =>
findByStatus(status).then((res) => setAssignments(res); );
,
[status],
);
return [
assignments,
setStatus,
];
;
const AssignmentListContainer = (props: status: string ) =>
const [assignments, setStatus] = useAssignmentListApi(props.status);
return (<AssignmentList assignments=assignments />);
;
export default AssignmentListContainer;
测试看起来像这样:
test('useAssignmentApi correctly sets the state', () =>
const mockReturnValue = [some: 'value'];
(AssignmentService.findByStatus as jest.Mock<any, any>)
.mockResolvedValue(mockReturnValue);
// Setup a dummy component to pass the custom hook
const TestHook = (props: callback: Function ) =>
const callback = props;
callback();
return <div />;
;
const testHook = (callback: Function) => mount(<TestHook callback=callback/>);
const component = testHook(() =>
const [assignments, setAssignment] = useAssignmentListApi('new');
setTimeout(() => expect(assignments).toEqual(mockReturnValue); , 10);
);
);
此测试适用于 setTimeout() 中的任何延迟,但如果我不在那里放入 setTimeout,总是会失败?我究竟做错了什么?
【问题讨论】:
删除async
关键字
这没有帮助@codekaizer
【参考方案1】:
我最终使用react-testing-library 并利用他们的waitForElement
api 来等待,直到我找到在数据提取完成后我会看到的元素/文本,然后断言呈现的值。
测试现在看起来像:
it('renders the list with the data returned by api', async () =>
const mockReturnValue = [
some: "value",
];
(AssignmentService.findByStatus as jest.Mock<any, any>)
.mockResolvedValue(mockReturnValue);
const container = render(<AssignmentListContainer status="new"/>);
// wait until api fetches data
await waitForElement(() => container.queryByText('Text I would expect after api call'));
// make assertions
expect(container.asFragment()).toMatchSnapshot();
);
【讨论】:
以上是关于在 useEffect 挂钩中进行的异步调用的测试结果的主要内容,如果未能解决你的问题,请参考以下文章
如何在useEffect(func,[])中使用异步api调用中的setState钩子测试组件
如何使用 jest/enzyme 测试 useEffect 与 useDispatch 挂钩?
我应该如何测试使用 Typescript 进行 api 调用的 React Hook “useEffect”?