Имитация клика по документу ReactJS/JSDom

Итак, я пишу несколько тестов для кода, который добавляет событие клика в документ. Я использую JSDom, ReactJS и Mocha/Chai. Я пробовал следующий код в тесте:

document.addEventListener('click', function() {
  console.log('test');
});
React.addons.TestUtils.Simulate.click(document);
//also tried React.addons.TestUtils.Simulate.click(document.body);

однако этот код не вызывает ожидаемое эхо.

Есть ли способ имитировать щелчок, клавиатуру и т.д. в документе с помощью JSDom и ReactJS?

UPDATE

Ответ Ник, я попытался добавить этот код к тесту:

document.body.addEventListener('click', function() {
  console.log('test');
});

document.body.click();

и я до тех пор, пока не получаю вывод журнала консоли. Я не уверен, есть ли какая-то проблема с JSDom и делаю такие вещи.

Если я не могу unit test этот код, это хорошо, уже есть код, который я не могу unit test прямо сейчас (код, для которого требуется реальная DOM, чтобы получить ширину, высоту и т.д...) но я хотел бы иметь возможность unit test большей части кода (и я не заинтересован в использовании PhantomJS для модульного тестирования). Мои интеграционные тесты будут охватывать этот тип кода.

UPDATE2

Другое дело, что при я console.log(document); я вижу объект, привязанный к свойству _listeners для click, поэтому я знаю, что событие привязано, оно просто не выполняется.

Ответ 1

Обновление: document.body.click будет работать в браузере, но для jsdom вам нужно вручную создать событие:

document.body.addEventListener('click', function() {
  console.log('test');
});

var evt = document.createEvent("HTMLEvents");
evt.initEvent("click", false, true);
document.body.dispatchEvent(evt)

Вышеприведенный код работает для меня в Jest и должен работать с "solo" jsdom.

Осень 2018 праздник обновления 🦃

Инструменты вокруг симуляции событий стали намного лучше. В настоящее время я переместил свой подход, чтобы использовать отличную библиотеку для тестирования реакции, чтобы отображать мои компоненты и события отправки:

import {render, fireEvent} from 'react-testing-library'

test('example', () => {
  const handleClick = jest.fn()

  const {getByText} = render(<div><button onClick={handleClick}>Click Me</button></div>)
  fireEvent.click(getByText('Click Me'))

  expect(handleClick).toHaveBeenCalled()
})

Хотя я все еще верю в тесты конца до конца с чем-то вроде кукловода или селена (или кипариса!), Обеспечивает наивысший уровень уверенности в том, что что-то действительно работает, это обеспечивает огромную ценность без загрязняющих тестов с ручным созданием события.

Ответ 2

React.addons.TestUtils.Simulate работает только с виртуальными событиями. Если вы хотите отправлять собственные события, вы можете сделать это непосредственно с помощью DOM api.

При имитации щелчка, если у вас есть компонент, который делает это:

<div>
   <button onClick={alert}>click me</button>
</div>

И у вас есть ссылка на <button/> в переменной с именем 'buttonEl' и запустите это:

React.addons.TestUtils.Simulate.click(buttonEl, 'hello world');

Вы получите предупреждение с "hello world" в нем. Все тестовые утилиты - это создание виртуального события, и пусть оно пузырится вверх по виртуальному дереву dom, вызывая обработчики событий на этом пути.

Ответ 3

Просто создайте Event и отправьте его:

// Add an event listeners to the document
document.addEventListener('click', function() {
    console.log('test');
});

// Create a new `click` event and `dispatch` it
var event = new MouseEvent('click')
document.dispatchEvent(event)

Ответ 4

Event.initEvent() устарело, и вместо этого должен использоваться конструктор Event().

// Add a click event listener to the document
document.addEventListener('click', function() {
    console.log('test');
});

// Create a click event with optional event initialisers: bubbles, cancelable and composed
var evt = new Event('click', { bubbles: false, cancelable: false, composed: false });

// Event can then be dispatched against any element, not only the document
document.dispatchEvent(evt);
myDiv.dispatchEvent(evt);

Поддержка браузера хороша, за исключением Internet Explorer.

Рекомендации: