Как протестировать свободное раскрывающееся меню пользовательского интерфейса с помощью библиотеки тестирования реакции?

Я новичок в библиотеке тестирования реакции, так что это может быть легко, но в настоящее время у меня есть раскрывающийся список, который я импортирую из свободного пользовательского интерфейса, и в настоящее время получаю ошибку "Элемент не имеет установщика значения", когда я пытаюсь его протестировать. используя библиотеку React Testing. Вот моя функция рендеринга.

import { Dropdown, IDropdownStyles, IDropdownOption } from 'office-ui-fabric-react/lib/Dropdown';
import { Stack } from 'office-ui-fabric-react/lib/Stack';


render() 
  {
    return (
      <div className="LandingPage">
        <h3>Here are some options</h3>
        <form onSubmit={this.handleSubmit}>
          <Stack>
            <Stack.Item align="center">
              <Dropdown
              placeholder="Select an option"
              label="Select an option"
              options={this.options}
              styles={this.dropdownStyles}
              onChange={this.handleChange}
              data-testid="myId"
            />
            </Stack.Item>
          </Stack>
        </form>
      </div>
    );
  }
}


Вот строка, которая терпит неудачу:

  const dropdownOption: IDropdownOption = {
    key: "0",
    text: "dropdownOption"
  }

fireEvent.click(queryByTestId("myId"), { target: { value: 'B' }, option: dropdownOption })
The given element does not have a value setter

    > 44 |   fireEvent.click(queryByTestId("myId"), { target: { value: 'B' }, option: dropdownOption })
         |             ^

3 ответа

Проблема заключается в реализации FluentUI компонента Dropdown. Если вы проверите сгенерированный HTML, вы обнаружите, что он просто стилизован <div>и что нет никаких элементов в качестве дочерних узлов.

Чтобы проверить, что в данный момент отображается при тестировании, вы можете добавить эту строку в свой тест, и он будет отображать «целый» HTML (если он достаточно мал, в противном случае увеличьте второй параметр на несколько нулей).

      screen.debug(undefined, 10000000);

Чтобы иметь возможность видеть эти <option>элементы, которые вы должны сначала нажать на <Dropdown>составная часть. После нажатия нового spanэлементы с ролью optionбудут отображаться, и вы можете получить к ним доступ.

Чтобы щелкнуть раскрывающийся список, вы можете использовать или из react-testing-library.

Чтобы выбрать один из вариантов, вы также должны нажать на него. Там я узнал, что почему-то userEventне работает, и вы должны использовать fireEvent.

Таким образом, весь пример может выглядеть так:

      import { act, fireEvent, render, screen } from '@testing-library/react';

test('select value from FluentUI Dropdown', async () => {
    render(<YourComponentWithDropdown/>);

    // Get the dropdown HTML element
    const dropdown = await screen.findByRole('combobox');
    expect(dropdown).toBeDefined();

    // Click on the dropdown
    userEvent.click(dropdown);

    // Find the option you want to select
    const option = (await screen.findByRole('option', { name: 'Bannana bread' })) as HTMLButtonElement;
    expect(option).toBeDefined();

    // Click on the option
    await act(async () => {
        fireEvent.click(option);
    });

    // Test what should follow after selection
});

Вы можете сослаться на этот ответ: как проверить реакцию-выбор с помощью библиотеки-тестирования-реакции, а не с плавным пользовательским интерфейсом, но очень похожим. не используйте щелчок или изменение, используйте keyDown + щелчок

const DOWN_ARROW = { keyCode: 40 };
fireEvent.keyDown(screen.getByLabelText('myId'), DOWN_ARROW);
fireEvent.click(screen.getByText('...your text'));  

и не используйте data-testid, вместо этого используйте aria-label.

Я обнаружил, что вам даже не нужно использовать fireEvent.keyDown, как если бы вы смотрели в шутливом снимке раскрывающегося компонента Fluent UI, все параметры раскрывающегося списка представляют собой выбираемые кнопки, которые доступны напрямую.

Вот что сработало для меня:

      const option = screen.getAllByText("myDropdownOption")[0];
fireEvent.click(option);

Я не мог понять, какой селектор использовать здесь, так как выбор по тексту возвращает несколько элементов, а селектор «кнопка» тоже не работал, поэтому я решил использовать getAllByText()[0]чтобы захватить первый элемент и щелкнуть по нему. Это не очень красивое решение, поэтому я отвел его в вспомогательную функцию, пока не будет найден правильный селектор.

Другие вопросы по тегам