Skip to main content

Testing

Forms

Testing forms is a common requirement in web applications. In this section, we will cover how to test forms using the @testing-library/react library.

Basic Form Testing

A simple form can be tested by rendering the component and simulating user interactions. Rely on the @testing-library/user-event library to simulate user actions like typing and clicking. You should also prefer interacting with the element via the element's label. In some cases the internals of a form component may duplicate role behaviors for browser compatibility. It is also simplest to validate the state of the form by submitting and checking the submitted values instead of checking the state of the form components directly.

❗Keep in mind that Forms in Kyber use Formik which handles submission and validation asyncronously. User interactions should be awaited to ensure that the form has been updated before making assertions. In some cases you may also need to wrap assertions in a waitFor block to ensure that the form has been updated.

it('textfield value change', async () => {
const user = userEvent.setup();
const mockOnSubmit = jest.fn();

render(
<Form onSubmit={mockOnSubmit}>
<FormField>
<TextField name="textfield" label="Text Field" />
</FormField>
</Form>,
);

await user.type(screen.getByLabelText('Text Field'), 'hello world');
await user.click(screen.getByRole('button', { name: 'Save' }));

expect(mockOnSubmit).toHaveBeenCalledWith({ textfield: 'hello world' }, expect.anything());
});

Tricky Form Testing

Sometimes forms can use components that have complex interactions like Select.

Select

Testing a Select component can be a bit more involved due to the way it handles options and user interactions. You can still use @testing-library/user-event to simulate selecting an option.

it('Nonsearchable, selects named item', async () => {
const user = userEvent.setup();
const mockOnSubmit = jest.fn();
const options = [
{
name: 'Georgia',
value: 'GA',
},
{
name: 'Iowa',
value: 'IA',
},
];

render(
<Form onSubmit={mockOnSubmit}>
<FormField>
<Select label="Select" name="select">
{options.map((option) => (
<Item key={option.value} {...option}>
{option.name}
</Item>
))}
</Select>
</FormField>
</Form>,
);

await user.click(screen.getByLabelText('Select'));
await user.click(screen.getByRole('option', { name: /georgia/i }));
await user.click(screen.getByRole('button', { name: 'Save' }));

expect(mockOnSubmit).toHaveBeenCalledWith({ select: 'GA' }, expect.anything());
});