Это оказывается очень сложным, когда вы используете 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 можно найти здесь: