如何使用 React 测试库测试下拉选择器是否在 React 中设置了值?

How to test that a dropdown selector has value set in React with React Testing Library?

具有以下代码:

    import { useForm, Controller } from 'react-hook-form';
    ...
      const { handleSubmit, reset, control, register, watch } = useForm({
        resolver: yupResolver(schema)
      });
    
    
    const availableSensorPoolOptions = [
      { id: '0', name: 'sensor pool 0' },
      { id: '1', name: 'sensor pool 1' },
      { id: '2', name: 'sensor pool 2' }
    ];
    
    
    ...

onSubmit={handleSubmit(onAddSubmit)} // the action when the submit is called

...
  const onAddSubmit = (data) => {
    postSignalMapping(data); // the API call if all is good
    toggle();
    reset();
  };

...
    
              <div data-testid={MapSignalModalTestIds.AVAILABLE_SENSOR_POOL}>
                <Controller
                  control={control}
                  name='availableSensorPool'
                  render={({ field: { onChange } }) =>
                    <SelectInput
                      label={t('calculation-engine.available-sensor-pool')}
                      initialSelectedOption={{ id: '0', name: '' }}
                      onChange={onChange}
                      options={availableSensorPoolOptions}
                    />
                  }
                />
              </div>

像thi这样的SelectInput有多个,但在本例中只有一个

const schema = yup.object().shape({
  availableSensorPool: yup.object().shape({
    id: yup.string(),
    name: yup.string()
  })
});

  const { handleSubmit, reset, control, register, watch } = useForm({
    resolver: yupResolver(schema)
  });

这是测试:

import { fireEvent, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

import { renderWithClientInstance } from '@oam/shared/test-utils';

import '@testing-library/jest-dom';
import MapSignalModal from './map-signal-modal';
describe('MapSignalModal', () => {
  const title = 'title';
  const toggle = jest.fn();
  const postSignalMapping = jest.fn();

  it('should call postSignalMapping function on clicking in Save button successfully', async () => {
    const { getByTestId, getByLabelText } = renderWithClientInstance(
      <MapSignalModal title={title} open={true} toggle={toggle} />
    );

    const saveButton = getByTestId('submit-button');
    expect(saveButton).toBeInTheDocument();

    userEvent.selectOptions(
      getByLabelText('calculation-engine.available-sensor-pool'),
      'sensor pool 0'
    );

    fireEvent.click(saveButton);

    await waitFor(() => {
      expect(postSignalMapping).toBeCalled();
    });
  });
});

失败并出现错误:

TestingLibraryElementError:在选项中找不到值“传感器池 0”

因此,由于 select 行为是使用 buttonspan 实现的。

您需要先单击按钮,这会将所有选项显示在屏幕上,然后您需要单击其中一个选项。

然后您终于可以测试所选的选项现在是否出现在屏幕上。

it("test dropdpwn", async () => {
  const { getByTestId, getByLabelText } = renderWithClientInstance(
    <MapSignalModal title={title} open={true} toggle={toggle} />
  );

  userEvent.click(screen.getAllByTestId("selectButton")[0]);
  userEvent.click(screen.getByText("sensor pool 1"));

  expect(
    await screen.findByText(screen.getByText("sensor pool 1"))
  ).toBeInTheDocument();
});

此外,为了确保您可以尝试以下操作,这应该会失败,因为“传感器池 1”选项最初不在屏幕上。

当文本更改为“传感器池 0”时它应该通过,因为它最初出现在屏幕上。

it("test dropdpwn", async () => {
  const { getByTestId, getByLabelText } = renderWithClientInstance(
    <MapSignalModal title={title} open={true} toggle={toggle} />
  );

  expect(screen.getByText("sensor pool 1")).toBeInTheDocument();
  // if you replace the above text to "sensor pool 0", it should work
});

为了测试 postSignalMapping 是否被调用,您可以模拟它,如下所示:

let mockPostSignalMapping = jest.fn();
jest.mock("../lib/hooks/use-post-signal-mapping", () => ({
  mutate: mockPostSignalMapping,
}));

it("test dropdpwn", async () => {
  // Do stuff

  await waitFor(() => {
    expect(mockPostSignalMapping).toBeCalled();
  });
});