【问题标题】:Testing results for async calls made in useEffect hook在 useEffect 挂钩中进行的异步调用的测试结果
【发布时间】: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

标签: reactjs jestjs enzyme react-hooks


【解决方案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();
  });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-07
    • 2019-11-10
    • 2021-11-07
    • 2019-11-22
    • 1970-01-01
    • 2020-05-16
    相关资源
    最近更新 更多