Mor*_*sis 7 javascript reactjs jestjs react-testing-library
I'm currenty trying to mock the react-select component and no matter what i do the firevent.change from react-testing-library seems to only fire on the first call of firevent.change.
I was wondering why the change was only firing once and how to fix it.
My jest mock is as follows:
jest.mock("react-select", () => ({ options, value, onChange }) => {
function handleChange(event) {
console.log("called");
const option = options.find(option => {
return option.value == event.currentTarget.value;
});
onChange(option);
}
return (
<select
id="uc"
data-testid="select"
value={value}
onChange={event => handleChange(event)}
>
{options?.map(({ label, value }) => (
<option key={value} value={value}>
{label}
</option>
))}
</select>
);
});
Run Code Online (Sandbox Code Playgroud)
As you can see its a fairly simple select block and i thought i should be able to call.
fireEvent.change(selectOptions[0], { target: { value: "0" } });
And this will work however if i then chain them together as in the following example:
test("Should render add another button and function", () => {
const mockSetOpen = jest.fn();
const { queryAllByTestId, getByTestId, getByLabelText, debug } = renderWithRedux(
<TabByRestraints setOpen={mockSetOpen} hidden={false} />,
{
userCatagories: userCategoriesMock,
permissionGroups: permissionGroupsMock,
roles: rolesMock
}
);
// Check that the user catagories exist and user catagories values
const selectOptions = queryAllByTestId("select");
expect(selectOptions).toHaveLength(2);
expect(getByTestId("user-category-row")).toBeTruthy();
fireEvent.change(selectOptions[0], { target: { value: "0" } });
fireEvent.change(selectOptions[1], { target: { value: "132" } });
expect(getByLabelText("Add a new user category restraint")).toBeTruthy();
});
Run Code Online (Sandbox Code Playgroud)
I can see that the console.log("called") is only fired once. The second select on the page is never has its value selected therfore the test fails.
I would like both change to dispatch a change event.
fireEvent.change(selectOptions[0], { target: { value: "0" } });
fireEvent.change(selectOptions[1], { target: { value: "132" } });
Run Code Online (Sandbox Code Playgroud)
However it only ever sets of the first.
Any help greatly appeciated.
您应该对选择的元素进行另一个查询。我会更进一步,以不同的方式命名它们,以使测试更易于阅读/调试。
// it's easier to have separate ids for each select, will be easier to read/maintain the test in the future
const firstSelect = queryByTestId("select1");
fireEvent.change(firstSelect, { target: { value: "0" } });
// a rerender might have happened so you need to query for the second select after the first event.
const secondSelect = queryByTestId("select2");
fireEvent.change(secondSelect, { target: { value: "132" } });
expect(getByLabelText("Add a new user category restraint")).toBeTruthy();
Run Code Online (Sandbox Code Playgroud)