Имитация нажатия клавиши на документе для модульного тестирования JEST

Использование JEST для модульного тестирования компонента, к документу которого прикреплен прослушиватель нажатия клавиш.

Как я могу проверить это в JEST? Как смоделировать событие нажатия клавиши в документе? Мне нужно, чтобы прослушиватель событий присутствовал в документе, поскольку он должен реагировать на действия клавиатуры независимо от элемента с фокусом.

РЕДАКТИРОВАТЬ: здесь вопрос касается моделирования события в документе или document.body. Все примеры относятся к фактическому узлу DOM, который работает нормально, а документ - нет.

Сейчас пытаюсь это сделать:

TestUtils.Simulate.keyDown(document, {keyCode : 37}); // handler not invoked

person Vaibhav Garg    schedule 10.11.2015    source источник
comment
Возможный дубликат React TestUtils.Simulate.keyDown не работает   -  person Henrik Andersson    schedule 10.11.2015


Ответы (3)


У меня была точно такая же проблема, и, к сожалению, я не смог найти подробностей о том, как решить эту проблему с помощью TestUtils.Simulate. Однако эта проблема натолкнула меня на идею просто вызвать .dispatchEvent с KeyboardEvent внутри моих шутливых тестов напрямую :

var event = new KeyboardEvent('keydown', {'keyCode': 37});
document.dispatchEvent(event);

Подробную информацию о KeyboardEvent можно найти здесь: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/KeyboardEvent

person Iris Schaffer    schedule 24.01.2016
comment
Спасибо за этот ответ. - person tiffon; 23.08.2016
comment
У меня сработало только при смене 'keydown' на 'keypress' - person paddotk; 27.09.2018
comment
Начиная с 2020 года и последней версии Jest, это работает для меня, если я использую global.dispatchEvent вместо window.dispatchEvent - person daniero; 24.06.2020

Вы также можете полностью заменить document.eventListener на фиктивную функцию перед монтированием компонента:

let events;
document.addEventListener = jest.fn((event, cb) => {
  events[event] = cb;
});

И смоделируйте событие, вызвав events[event] после установки, например:

events.keydown({ keyCode: 37 })

Кроме того, довольно удобно выполнять первую часть в beforeEach() функции, если у вас много тестов, связанных с событиями DOM.

person andrianov    schedule 17.01.2019

Следуя ответу @Iris Schaffer, если в вашем коде используются ключи ctrl/alt/shift, вам нужно будет их инициализировать, а также имитировать реализацию метода getModifierState на KeyboardEvent

const keyboardEvent = new KeyboardEvent('keydown', { keyCode, shiftKey, altKey, ctrlKey });
jest.spyOn(keyboardEvent, 'getModifierState').mockImplementation((modifier) => {
     switch (modifier) {
          case 'Alt':
               return altKey;
          case 'Control':
               return ctrlKey;
          case 'Shift':
               return shiftKey;
     }
});
person MichaelS    schedule 18.05.2020