简体   繁体   English

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

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

Having the following code:具有以下代码:

    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>

There are multiple SelectInput s like thi, but in this example it will be only one有多个这样的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)
  });

And here is the test:这是测试:

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();
    });
  });
});

it fails with the error:它失败并出现错误:

TestingLibraryElementError: Value "sensor pool 0" not found in options TestingLibraryElementError:在选项中找不到值“传感器池 0”

So, since the select behavior is being achieved using a button and span s.因此,由于select行为是使用buttonspan来实现的。

You need to first click the button this would bring all the options on the screen and then you need to click one of those options.您需要首先单击按钮,这将在屏幕上显示所有选项,然后您需要单击其中一个选项。

And then you can finally test that the selected option is now on the screen.然后您最终可以测试所选选项现在是否在屏幕上。

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();
});

Also, to be really sure you can try the following, this should fail because "sensor pool 1" option is not initially on the screen.此外,为了确保您可以尝试以下操作,这应该会失败,因为“传感器池 1”选项最初不在屏幕上。

And it should pass when the text is changed to "sensor pool 0" because that's there on the screen initially.它应该在文本更改为“传感器池 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
});

For testing if postSignalMapping is being called you can mock it as shown below:为了测试是否正在调用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();
  });
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM