useEffect 钩子中进行的异步调用的测试结果
2019-08-19
2306
我试图断言我的自定义钩子在挂载时会从 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,它总是会失败?我做错了什么?
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();
});
cipher
2019-08-19