首页 > 解决方案 > 没有调用 React-Testing-Library 模拟函数?

问题描述

我想测试一个被调用函数的实现。我正在测试的基本组件是,特别是onSkipTask功能:

...

export const TasksList: React.FC<TasksListProps> = ({ tasks }) => {
  const [modalOpen, openModal, closeModal, modalTaskId] = useModal();
  const { mutate: createUserTask } = useCreateUserTask();
  const { data: userTasks } = useQueryUserTasks({ category });
  const { data: user } = useQueryUser();

  const onSkipTask = () => {
    if (!modalTaskId || !user?.userId) return null;

    // This console.log is being called, which (I think) means the function is called also
    console.log('createUserTask', {
      userId: user.userId,
      taskId: modalTaskId,
      category,
      status: 'SKIPPED',
    });

    createUserTask({
      userId: user.userId,
      taskId: modalTaskId,
      category,
      status: 'SKIPPED',
    });
    closeModal();
  };

  return (
    <>
      {modalOpen && modalTaskId && (
        <ConfirmModal
          closeModal={closeModal}
          onConfirm={onSkipTask}
          confirmText="Yes, skip"
          text="I'm sure I want to skip this task"
        />
      )}
      <TasksListContainer>
        {tasks.map((task) => (
          <TaskItem
            key={task.taskId}
            {... { task, status, variant, openModal }}
          />
        ))}  
      </TasksListContainer>
    </>
  );
};

因此,正如您在上面看到的,有一些钩子,我在我的测试以及 console.log 中模拟了这些钩子,因此我可以在测试中看到函数是否使用正确的数据调用(剧透;它是)。

所以这把我带到了测试本身。我添加了一些评论来澄清正在发生的事情。

jest.mock('queries/tasks');
const mockUseCreateUserTask = mockedTasks.useCreateUserTask as jest.Mock;
const mockUseQueryTasks = mockedTasks.useQueryTasks as jest.Mock;
const mockUseQueryUserTasks = mockedTasks.useQueryUserTasks as jest.Mock;

beforeEach(() => {
  mockUseCreateUserTask.mockImplementation(() => ({
    mutate: jest.fn(() => console.log('mock')),
  }));

  mockUseQueryTasks.mockImplementation(() => ({
    status: 'success',
    data: allTasks,
  }));

  mockUseQueryUserTasks.mockImplementation(() => ({
    status: 'success',
    data: userTasks,
  }));
});

afterEach(() => {
  cleanup();
  jest.resetAllMocks();
});

test('<Category /> skip a task', async () => {
  const { debug, findAllByTestId, findByTestId, queryByTestId } = render(<Category />, { wrapper: TestWrapper });
  const { mutate: createUserTask } = mockUseCreateUserTask();

  const skipBtn = await findAllByTestId('skipButton');
  expect(skipBtn).toBeTruthy();
  expect(queryByTestId('modalConfirm')).toBeFalsy();

  fireEvent.click(skipBtn[0]);

  const modalConfirmBtn = await findByTestId('modalConfirm');
  expect(modalConfirmBtn).toBeTruthy();
  expect(createUserTask).not.toHaveBeenCalled();

  // DOM tree of Modal is visible debug()

  fireEvent.click(modalConfirmBtn);
  expect(queryByTestId('modalConfirm')).toBeFalsy();

  // Modal is removed from the DOM
  // since closeModal() is the function right after createUserTask()
  expect(createUserTask).toHaveBeenCalled(); 
  // The test keeps faling there and returns 0 calls

  debug();
});

正如你所看到的,我正在做一些模拟以确保所有数据都被覆盖。我还在从返回中嘲笑useCreateUserTask()and mutate(来自react-querybtw)函数(应该被调用)。

如您所见,我还尝试让模拟的变异返回一个console.log,甚至那个被调用。尽管expect(createUserTask).toHaveBeenCalled();不断返回 0 个电话,但我似乎无法弄清楚为什么会一直发生这种情况。我很想得到任何帮助或建议,在此先感谢!

还有一个显示测试结果的屏幕截图: 在此处输入图像描述

标签: jestjsmockingreact-testing-library

解决方案


推荐阅读