使用React测试库测试由Redux连接的独立组件的首选方法是什么

pkwftd7m  于 2023-04-12  发布在  React
关注(0)|答案(1)|浏览(113)
  • 我知道https://redux.js.org/usage/writing-tests上的Redux文档。我的设置函数用<Provider> Package 了每个渲染组件,因此它可以访问商店。
  • 我知道React测试库测试集成行为而不是实现的哲学。

我有一个应用程序,其中2个不同的,深度嵌套的组件通过Redux相互交互。Component A有一组按钮,当按下按钮时,Component B会改变其视图。

我有两种方法来测试它。

隔离

1.渲染组件A
1.测试它是否正确分派操作。
1.渲染组件B
1.在测试中分派相同的操作
1.检查组件是否正确响应派单。

集成

1.渲染整个应用程序
1.模拟组件A上的咔哒声
1.检查组件B是否正确React,而无需手动调用任何Redux函数。
我觉得集成的方法符合RTL的哲学。但我不能接受这样一个事实,即我需要渲染整个应用程序来测试与确切组件相关的功能。我甚至不知道在哪里放置这样的测试。
应该是ComponentB.test.tsx还是App.test.tsx,因为我正在渲染整个应用程序?
如果我有很多这样的测试,App.test.tsx会很混乱,或者我应该把它放在ComponentB.test.tsx里面,但是在测试里面呈现App组件?
或者我应该接受这样一个事实,即当测试与Redux相关时,我正在测试实现?
任何想法都很感激。谢谢。

w46czmvw

w46czmvw1#

React测试库适合单元测试和集成测试。在你的情况下,你应该在以下代码中编写2个测试:

  • ComponentA.test.tsx
  • ComponentB.test.tsx

utils/renderWithProvider.ts

import { ReactElement } from 'react';
import { Provider } from 'react-redux';
import { PreloadedState } from '@reduxjs/toolkit';
import { render, RenderOptions } from '@testing-library/react';
import { setupStore, AppStore, RootState } from 'store';

interface ExtendedRenderOptions extends Omit<RenderOptions, 'queries'> {
  preloadedState?: PreloadedState<RootState>;
  store?: AppStore;
}

// eslint-disable-next-line import/prefer-default-export
export const renderWithProviders = (
  component: ReactElement,
  {
    preloadedState = {},
    // Automatically create a store instance if no store was passed in
    store = setupStore(preloadedState)
  }: // ...renderOptions
  ExtendedRenderOptions = {}
) => render(<Provider store={store}>{component}</Provider>);

ComponentA.test.tsx

import { cleanup, screen, RenderResult } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { renderWithProviders } from 'utils/renderWithProviders';
import ComponentA from '..';

const dispatchMock = jest
  .spyOn(store, 'dispatch')
  .mockImplementation(() => jest.fn());
jest.mock('store/yourData/yourDataSlice', () => ({
  setYourData: (data) => dispatchMock(data)
}));

describe('<ComponentA />', () => {
  let view: RenderResult;

  beforeEach(() => {
    view = renderWithProviders(<ComponentA />);
  });

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

  it('should render', () => {
    expect(view.asFragment()).toMatchSnapshot();
  });

  it('click on button', async () => {
    const button = screen.getByRole('button');
    await userEvent.click(button);

    expect(dispatchMock).toHaveBeenCalledWith('some data');
  });
});

...
整个应用程序的测试是e2 e测试的一项任务。

相关问题