Jest mock for react-select or react-testing-library on change not firing on target change

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.

tud*_*ely 4

您应该对选择的元素进行另一个查询。我会更进一步,以不同的方式命名它们,以使测试更易于阅读/调试。

  // 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)