Реагирование библиотеки тестирования на изменение компонента Выбор пользовательского интерфейса материала - PullRequest
3 голосов
/ 15 марта 2019

Я пытаюсь проверить onChange событие Выберите компонент , используя реагирующая библиотека-тестирования .

Я беру элемент, используя getByTestId, который прекрасно работает, затем устанавливаю значение элемента и затем вызываю fireEvent.change(select);, но onChange никогда не вызывается и состояние никогда не обновляется.

Я попытался использовать как сам компонент select, так и захватить ссылку на базовый элемент input, но ни один из них не работает.

Какие-нибудь решения?Или это известная проблема?

1 Ответ

2 голосов
/ 15 марта 2019

Это оказывается очень сложным, когда вы используете Material-UI Select с native={false} (по умолчанию). Это связано с тем, что отображаемый ввод даже не имеет HTML-элемента <select>, а представляет собой смесь элементов div, скрытого ввода и некоторых svgs. Затем, когда вы нажимаете на кнопку выбора, отображается слой презентации (вроде модального) со всеми вашими опциями (кстати, это не <option> элементы HTML), и я считаю, что это нажатие одного из эти опции, которые запускают все, что вы передали как обратный вызов onChange к вашему исходному интерфейсу Material * UI <Select>

Все это говорит о том, что если вы хотите использовать <Select native={true}>, тогда у вас будут фактические HTML-элементы <select> и <option> для работы, и вы можете запустить событие изменения на <select> как Вы бы ожидали.

Вот тестовый код из песочницы кода, который работает:

import React from "react";
import { render, cleanup, fireEvent } from "react-testing-library";
import Select from "@material-ui/core/Select";

beforeEach(() => {
  jest.resetAllMocks();
});

afterEach(() => {
  cleanup();
});

it("calls onChange if change event fired", () => {
  const mockCallback = jest.fn();
  const { getByTestId } = render(
    <div>
      <Select
        native={true}
        onChange={mockCallback}
        data-testid="my-wrapper"
        defaultValue="1"
      >
        <option value="1">Option 1</option>
        <option value="2">Option 2</option>
        <option value="3">Option 3</option>
      </Select>
    </div>
  );
  const wrapperNode = getByTestId("my-wrapper")
  console.log(wrapperNode)
  // Dig deep to find the actual <select>
  const selectNode = wrapperNode.childNodes[0].childNodes[0];
  fireEvent.change(selectNode, { target: { value: "3" } });
  expect(mockCallback.mock.calls).toHaveLength(1);
});

Вы заметите, что вам нужно рыться в узлах, чтобы найти фактическое значение <select>, когда Material-UI отображает его <Select>. Но как только вы найдете его, вы можете сделать на нем fireEvent.change.

CodeSandbox можно найти здесь:

Edit firing change event for material-ui select

...