如何使用 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
行为是使用 button
和 span
实现的。
您需要先单击按钮,这会将所有选项显示在屏幕上,然后您需要单击其中一个选项。
然后您终于可以测试所选的选项现在是否出现在屏幕上。
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();
});
});
具有以下代码:
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
行为是使用 button
和 span
实现的。
您需要先单击按钮,这会将所有选项显示在屏幕上,然后您需要单击其中一个选项。
然后您终于可以测试所选的选项现在是否出现在屏幕上。
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();
});
});