App.js
import React, { Component } from "react";
import Select from "react-select";
const SELECT_OPTIONS = ["FOO", "BAR"].map(e => {
return { value: e, label: e };
});
class App extends Component {
state = {
selected: SELECT_OPTIONS[0].value
};
handleSelectChange = e => {
this.setState({ selected: e.value });
};
render() {
const { selected } = this.state;
const value = { value: selected, label: selected };
return (
<div className="App">
<div data-testid="select">
<Select
multi={false}
value={value}
options={SELECT_OPTIONS}
onChange={this.handleSelectChange}
/>
</div>
<p data-testid="select-output">{selected}</p>
</div>
);
}
}
export default App;
App.test.js
import React from "react";
import {
render,
fireEvent,
cleanup,
waitForElement,
getByText
} from "react-testing-library";
import App from "./App";
afterEach(cleanup);
const setup = () => {
const utils = render(<App />);
const selectOutput = utils.getByTestId("select-output");
const selectInput = document.getElementById("react-select-2-input");
return { selectOutput, selectInput };
};
test("it can change selected item", async () => {
const { selectOutput, selectInput } = setup();
getByText(selectOutput, "FOO");
fireEvent.change(selectInput, { target: { value: "BAR" } });
await waitForElement(() => getByText(selectOutput, "BAR"));
});
This minimal example works as expected in the browser but the test fails. I think the onChange handler in is not invoked. How can I trigger the onChange callback in the test? What is the preferred way to find the element to fireEvent at? Thank you
In my project, I'm using react-testing-library and jest-dom. I ran into same problem - after some investigation I found solution, based on thread: https://github.com/airbnb/enzyme/issues/400
Notice that the top-level function for render has to be async, as well as individual steps.
There is no need to use focus event in this case, and it will allow to select multiple values.
Also, there has to be async callback inside getSelectItem.
This got to be the most asked question about RTL :D
The best strategy is to use
jest.mock
(or the equivalent in your testing framework) to mock the select and render an HTML select instead.For more info on why this is the best approach, I wrote something that applies to this case too. The OP asked about a select in Material-UI but the idea is the same.
Original question and my answer:
This is an example of how you could mock a select:
You can read more here.