使用中进行的异步调用的测试结果

时间:2019-08-19 02:58:46

标签: reactjs jestjs enzyme react-hooks

我试图断言我的Custom挂接在挂载时会从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 个答案:

答案 0 :(得分:0)

我最终使用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();
  });