vendredi 30 novembre 2018

Unit Test: How to mock document.getElementsByClassName() in react?

I have this component i did with create-react-app and i want to test following function with jest/enzyme.

(The function triggers when the up/down arrows are pressed in an input)

handleArrow(e) {
  const list = document.getElementsByClassName('search__dropdown')[0];
  const len = document
    .getElementsByClassName('search__dropdown-option').length;
  const arr = Array.from(document
    .getElementsByClassName('search__dropdown-option'));
  let selected = document
    .getElementsByClassName('search__dropdown-option--selected')[0];
  let index = arr.indexOf(selected);
  let next = null;

  if (index === -1 && list) {
    index = 0;
    selected = list.getElementsByClassName('search__dropdown-option')[0];
    selected.classList.add('search__dropdown-option--selected');
  } else if (e === 40 && list) {
    if (selected) {
      index++;
      selected.classList.remove('search__dropdown-option--selected');
      next = list.getElementsByClassName('search__dropdown-option')[index];
      if (next !== undefined && index <= len) {
        selected = next;
      } else {
        index = 0;
        selected = list.getElementsByClassName('search__dropdown-option')[0];
        selected.classList.add('search__dropdown-option--selected');
      }
      selected.classList.add('search__dropdown-option--selected');
    }
  } else if (e === 38 && list) {
    if (selected) {
      index--;
      selected.classList.remove('search__dropdown-option--selected');
      next = list.getElementsByClassName('search__dropdown-option')[index];
      if (next !== undefined && index >= 0) {
        selected = next;
      } else {
        index = len - 1;
        selected = list
          .getElementsByClassName('search__dropdown-option')[index];
        selected.classList.add('search__dropdown-option--selected');
      }
      selected.classList.add('search__dropdown-option--selected');
    }
  }
}

So far, i have tried this:

it('should work', () => {
  const dropdown = global.document.createElement('div');
  const option = global.document.createElement('div');
  const selected = global.document.createElement('div');
  dropdown.classList.add('search__dropdown');
  option.classList.add('search__dropdown-option');
  selected.classList.add('search__dropdown-option--selected');
  global.document.body.appendChild(dropdown);
  dropdown.appendChild(option);
  dropdown.appendChild(selected);

  jest.useFakeTimers();
  const comp = mount(<Search/>);
  comp.setState({
    fetching: true,
    searchInput: 'the',
    onInput: true,
    searchResults: data,
    filteredSearch: filtered,
  });
  comp.setState({searchInput: 'the'});
  comp.find('.search__input').simulate('keydown', {key: 'Enter'});
  comp.find('.search__dropdown-option').at(0).simulate('click');
  jest.runAllTimers();
  comp.unmount();
});

When i run the test the "list" variable is always undefined (thing that i don't understand because the line comp.find('.search__dropdown-option') works, so there's there's gotta be search__dropdown in the DOM ,right?)

Thanks in advance.

Aucun commentaire:

Enregistrer un commentaire