testing select element in react with Jest
Solution 1
I suggest you to use the userEvent from the React Testing Library.
It's very straightforward and simple to use. Here is the provided example:
import React from "react";
import { render } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
test("select values", () => {
const { getByTestId } = render(
<select multiple data-testid="select-multiple">
<option data-testid="val1" value="1">
1
</option>
<option data-testid="val2" value="2">
2
</option>
<option data-testid="val3" value="3">
3
</option>
</select>
);
userEvent.selectOptions(getByTestId("select-multiple"), ["1", "3"]);
expect(getByTestId("val1").selected).toBe(true);
expect(getByTestId("val2").selected).toBe(false);
expect(getByTestId("val3").selected).toBe(true);
});
Solution 2
I found a way to do this using Simulate from react-dom test-utils.
import React from "react";
import { render, unmountComponentAtNode } from "react-dom";
import { act, Simulate } from "react-dom/test-utils";
test("Should change preference", () => {
act(() => {
render(<TestSelect/>, container);
});
let message = container.querySelector("h4");
expect(message.innerHTML).toContain("apples");
const selectElement = container.querySelector("select");
act(() => {
Simulate.change(selectElement, { target: { value: "oranges" }});
});
message = container.querySelector("h4");
expect(message.innerHTML).toContain("oranges");
});
Related videos on Youtube
![Adam D](https://i.stack.imgur.com/oNs64.jpg?s=256&g=1)
Adam D
I love open source, collaboration, and thinking about how software can help language learning.
Updated on June 04, 2022Comments
-
Adam D about 2 years
I am trying to test functionality of a select element in a React component.
Note: This is not a duplicate of this question because I am not using enzyme, but rather trying to do things simply using
act()
from React's Test Utilities and running tests with Jest.Given a component with a select element like this:
class TestSelect extends React.Component { constructor(props) { super(props); this.state = { choice: "apples", }; this.handleChange = this.handleChange.bind(this); } handleChange(event) { this.setState({choice: event.target.value}); } render() { return ( <div> <select value={this.state.choice} onChange={this.handleChange}> <option value="apples">apples</option> <option value="oranges">oranges</option> </select> <h4>You like {this.state.choice}</h4> </div> ); } }
I would like to be able to test it like this:
import React from "react"; import { render, unmountComponentAtNode } from "react-dom"; import { act } from "react-dom/test-utils"; test("Should change preference", () => { act(() => { render(<TestSelect/>, container); }); let message = container.querySelector("h4"); expect(message.innerHTML).toContain("apples"); const selectElement = container.querySelector("select"); act(() => { selectElement.dispatchEvent(new Event("change"), { target: { value: "oranges"}, bubbles: true, }); }); message = container.querySelector("h4"); // Test fails here: Value does not change expect(message.innerHTML).toContain("oranges"); });
After a lot of fiddling and trying different options I am not able to simulate an event that ends up changing the selected value in the select element.