Search code examples
reactjsunit-testingreact-hooksjestjsreact-testing-library

Unable to fire a "change" event - please provide a DOM element


I am writing a unit test case using jest and react testing library for event invoked by change in dropdown options in React. The code for Component is as follows:

import React,{useState} from "react";
import "./App.css";

function App() {
  const [value, setValue] = useState("fruit")

  function selectionChange(params) {
    console.log(params)
    setValue(params)
  }
  return (
    <div className="App">
      <div>
        <select data-test-id="Oshop" onChange={(e) => selectionChange(e.target.value)}>
          <option value="fruit">Fruit</option>

          <option value="vegetable">Vegetable</option>

          <option value="meat">Meat</option>
        </select>
      </div>
    </div>
  );
}

export default App;

And the code for unit test is as follows:

import { fireEvent, render, screen } from '@testing-library/react';
import App from './App';



test('testing onchange event for oshop', () => {
  render(<App />);
  const dropdElement = screen.queryByTestId("Oshop")
  fireEvent.change(dropdElement,{target:{value:"meat"}})
  expect(dropdElement.value).toBe("meat")
});

First when I was using getTestById then I was getting error as

TestingLibraryElementError: Unable to find an element by: [data-testid="Oshop"]

Then again I tried with queryByTestId and I started getting error as

Unable to fire a "change" event - please provide a DOM element.


Solution

  • It should be data-testid, not data-test-id, see ByTestId

    E.g.

    App.tsx:

    import React, { useState } from "react";
    
    function App() {
      const [selectedValue, setSelectedValue] = useState()
      function selectionChange(value) {
        console.log(value)
        setSelectedValue(value);
      }
      return (
        <div className="App">
          <select value={selectedValue} data-testid="Oshop" onChange={(e) => selectionChange(e.target.value)}>
            <option value="fruit">Fruit</option>
            <option value="vegetable">Vegetable</option>
            <option value="meat">Meat</option>
          </select>
        </div>
      );
    }
    
    export default App;
    

    App.test.tsx:

    import React from 'react';
    import { fireEvent, render, screen } from '@testing-library/react';
    import '@testing-library/jest-dom';
    import App from './App';
    
    test('testing onchange event for oshop', (done) => {
      render(<App />);
      const dropdElement = screen.queryByTestId("Oshop");
      expect(dropdElement).toHaveValue(undefined);
      if (!dropdElement) return done('select element not found');
      fireEvent.change(dropdElement, { target: { value: "meat" } });
      expect(screen.getByTestId('Oshop')).toHaveValue('meat');
      done();
    });
    

    Test result:

     PASS  stackoverflow/76117012/App.test.tsx (6.713 s)
      ✓ testing onchange event for oshop (36 ms)
    
      console.log
        meat
    
          at selectionChange (stackoverflow/76117012/App.tsx:6:13)
    
    ----------|---------|----------|---------|---------|-------------------
    File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
    ----------|---------|----------|---------|---------|-------------------
    All files |     100 |      100 |     100 |     100 |                   
     App.tsx  |     100 |      100 |     100 |     100 |                   
    ----------|---------|----------|---------|---------|-------------------
    Test Suites: 1 passed, 1 total
    Tests:       1 passed, 1 total
    Snapshots:   0 total
    Time:        7.013 s
    

    package versions:

    "@testing-library/jest-dom": "^5.11.6",
    "@testing-library/react": "^11.2.7",
    "react": "^16.14.0",
    "react-dom": "^16.14.0",
    "jest": "^26.6.3",