如何使用React测试库测试RTK Query?

5

我正在尝试使用RTK Query进行开发,但找不到一个好的示例来展示如何使用React测试库编写使用RTK Query请求的组件的单元测试。例如,我们有一个组件从服务器获取某些东西的列表。如何为请求模拟数据?我发现可以使用mswjs在测试中模拟API,但即使这样,我仍然有一个问题 - 在检查集合中是否存在某些内容之前,我需要添加“await new Promise((r) => setTimeout(r, 1000));” 的延迟。也许,有人知道如何使用RTK Query测试组件吗?


小更新 - 不需要使用 await new Promise((r) => setTimeout(r, 1000)); 因为可以使用 waitForElementToBeRemoved 来等待移除加载器。但是也许有人有使用 RTK Query 进行组件单元测试的例子。 - Denis
请提供足够的代码,以便他人更好地理解或重现问题。 - Community
3个回答

15

您可以查看RTK Query本身的测试

一些提示:

  • 使用msw模拟API
  • 在真正的Redux store中包装您的组件与API(例如示例中的storeRef.wrapper
  • 使用一些工具等待UI变化,例如:
      await waitFor(() =>
        expect(screen.getByTestId('isFetching').textContent).toBe('false')
      )

5
我发现的一种替代方法是模拟rtk查询钩子本身。然后,您可以为数据对象设置任何您想要的内容。

jest.mock('pathToHook', () => ({
  __esModule: true,
  default: () => () => { data: 'whatever you want' },
}))


3
但是如果我们谈论由RTK生成的默认钩子,pathToHook会是什么样子呢? - sergioviniciuss

2
你应该能够做到这样的事情。
import React from 'react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { useGetData } from './api'; // RTK Query API

import MyComponent from './MyComponent';

jest.mock('./useGetData');

describe('MyComponent', () => {
  beforeEach(() => {
    useGetData.mockClear();
  });

  it('should render data after API request', async () => {
    const mockData = {
      id: 1,
      name: 'John Doe',
      email: 'johndoe@example.com'
    };
    useGetData.mockReturnValueOnce({
      data: mockData,
      isLoading: false,
      isSuccess: true,
      isError: false,
      error: null,
    });

    render(<MyComponent />);

    // Check that loading state is not displayed
    expect(screen.queryByText('Loading...')).toBeNull();

    // Check that data is displayed correctly
    expect(screen.getByText('Name: John Doe')).toBeInTheDocument();
    expect(screen.getByText('Email: johndoe@example.com')).toBeInTheDocument();
  });
});

在这个例子中,我们正在测试MyComponent在成功调用useGetData钩子后是否正确显示数据。我们通过使用jest.mock模拟它并使用useGetData.mockReturnValueOnce设置模拟返回值来模拟useGetData钩子。然后,我们渲染组件并使用expect语句验证未显示加载状态并且正确显示数据。值得注意的是,我们不需要等待API请求完成,因为useGetData已经返回了我们希望测试的数据。

非常感谢您的回答。您节省了我很多时间。 - Adam
const hookMocked = jest.fn(); jest.mock('path-to-the-module-you-want-to-mock', () => ({ hookThatYouWantToMock: () => hookMocked(), }));然后你可以在beforeEach()中使用mockClear(),在测试中使用mockReturnValueOnce() :) - Bozhidar Petrov
嘲笑一个变异或懒惰的查询,你怎么做呢? - augusticor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接