Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I test a debounce function with Jest/Enzyme?

I have this component where test coverage says I need to test lines 24 and 25:

class TableToolbarComp extends Component {
  state = {
    shipmentId: '',
  };

  debouncedSetFilters = debounce(() => {
    const { applyFilters } = this.props; // LINE 24
    applyFilters(this.state);            // LINE 25
  }, 750);

  updateShipmentId = ev => {
    this.setState(
      {
        shipmentId: ev.target.value,
      },
      this.debouncedSetFilters,
    );
  };

  render() {...}
}

And the test:

  beforeEach(() => {
    applyFilters: k => k,
  });

...

  it('should trigger button click', () => {
    const wrapper = shallow(<TableToolbarComp {...props} />);

    wrapper.instance().debouncedSetFilters(750);
    wrapper.instance().updateShipmentId({ target: { shipmentId: '124' } });
    wrapper.instance().props.applyFilters({ shipmentId: '124' });
  });

And I am not getting any errors, it just says those 2 lines need coverage.

I already attempted to called debouncedSetFilters and applyFilters on the test but it's still returning those 2 lines as uncover.

What am I missing?

like image 940
Reacting Avatar asked Oct 28 '25 03:10

Reacting


1 Answers

Function calls cannot be tested efficiently without spies. It should be:

  beforeEach(() => {
    applyFilters = jest.fn();
  });

In order to test asynchronous time-sensitive function, timer mocks should be applied:

jest.useFakeTimers();

const wrapper = shallow(<TableToolbarComp applyFilters={applyFilters} />);

wrapper.instance().debouncedSetFilters();
wrapper.instance().debouncedSetFilters();
expect(applyFilters).not.toHaveBeenCalled();
jest.advanceTimersByTime(750);
expect(applyFilters).toHaveBeenCalledTimes(1);

Then debouncedSetFilters can be stubbed in updateShipmentId test.

like image 180
Estus Flask Avatar answered Oct 29 '25 19:10

Estus Flask