Search code examples
javascriptreactjsjestjsreact-testing-libraryreact-test-renderer

React test unable to find an element mocked with jest


I am trying to mock a react select component for using it in a test firing event. Below is my react select that I created using jest.

jest.mock("react-select", () => ({ options, onChange }) => {
  function handleChange(event) {
    const option = [];
    option.push(options.find(option => option === event.currentTarget.value));
    onChange(option);
    console.log(option);............................................................//line 1
  }
  return (
    <select
      data-testid="test-select"
      name="users"
      label="users"
      options={[
        "a",
        "b",
        "c",
        "d",
        "e"
      ]}
      onChange={handleChange}
    >
      {options.map(value => (
        <option key={value} value={value}>
          {value}
        </option>
      ))}
    </select>
  );
});

The problem is that the console on line 1 prints undefined in the console. Below is the fire event mockup for my test:

const chooseInput = getByTestId("test-select");
    fireEvent.change(chooseInput, {
      target: {
        value: "b"
      }
    });

The test fails as:

expect(received).toBeInTheDocument()

    received value must be an HTMLElement or an SVGElement.
    Received has value: null

Why the option is not updated at the onset of Fire Event?


Solution

  • The structure for mocking default exports from a library is:

    jest.mock("react-select", () => {
      return {
        __esModule: true,
        default: ({ options, onChange }) => {
          // Your mock implementation goes here
        },
      };
    })
    

    The __esModule: true is important

    The main function needs to return an object with a default property that represents your mocked implementation

    So the complete code should be

    jest.mock("react-select", () => {
      return {
        __esModule: true,
        default: ({
          options,
          onChange
        }) => {
          function handleChange(event) {
            const option = [];
            option.push(options.find(option => option === event.currentTarget.value));
            onChange(option);
            console.log(option);
          }
          return ( <
            select data - testid = "test-select"
            name = "users"
            label = "users"
            options = {
              [
                "a",
                "b",
                "c",
                "d",
                "e"
              ]
            }
            onChange = {
              handleChange
            } > {
              options.map(value => ( <
                option key = {
                  value
                }
                value = {
                  value
                } > {
                  value
                } <
                /option>
              ))
            } <
            /select>
          );
        },
      };
    })