How to test a situation where user selects option from data list? I am asserting onChange
callback on the input using @testing-library/user-event
.
This is my React component:
// MyInput.js
import React from "react";
const MyInput = ({ value, list, id, onChange }) => {
return (
<label>
<strong>{id}</strong>
<div>
<input type="text" value={value} onChange={onChange} list={id} />
<datalist id={id} aria-label="datalist-items">
{list.map((item) => (
<option
key={`item-${item.id}`}
aria-label="data-list-item"
value={item.value}
/>
))}
</datalist>
</div>
</label>
);
};
export default MyInput;
This is my failing test
// MyInput.spec.js
import React from "react";
import { render } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import MyInput from "./MyInput";
import data from "./data.json";
describe("MyInput", () => {
it("should trigger onChange with selected option", () => {
const onChange = jest.fn();
const list = [...data.list];
const screen = render(<MyInput onChange={onChange} list={list} />);
userEvent.selectOptions(screen.getByLabelText("datalist-items"), "first");
expect(onChange).toHaveBeenCalledWith("first");
});
});
Data provided to component:
// data.json
{
"list": [
{ "id": 1, "value": "first" },
{ "id": 2, "value": "second" }
]
}
However that does not work. Test reports failure:
expect(jest.fn()).toHaveBeenCalledWith(...expected)
Expected: "first"
Number of calls: 0
14 | userEvent.selectOptions(screen.getByLabelText("datalist-items"), "first");
> 16 | expect(onChange).toHaveBeenCalledWith("first");
17 | });
18 | });
You can find a live example in this CodeSandbox.
I want to simulate real-life scenario where user clicks into an input, the data list is rendered and user clicks one of the options. Should I be somehow targeting the rendered datalist instead? And how?
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…