2016-08-05 10 views
6

Компонент, который я пишу, должен изменить его поведение в зависимости от того, нажата ли кнопка ctrl.Экранное событие для тестового окна в Reactjs

Я использую window.onkeydown событие, но Simulate от Реагировать Test Utils не позволяет мне отправлять события против window. Я также пробовал window.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 17 }));, но mocha/node не распознает KeyboardEvent.

Есть ли способ для тестирования window.onkeydown с использованием Утилиты для испытаний на реакцию? если нет, есть ли лучший способ сделать это в мокко для узла?

Вот код для ilustrate вопрос:

describe('On Keydown',() => { 
    it('fires the event',() => { 
     // Component 
     const Component = class extends React.Component { 
      constructor(props) { 
       super(props); 
       this.state = { key: false }; 
       window.addEventListener('keydown', e => this.setState({ key: true })); 
       window.addEventListener('keyup', e => this.setState({ key: false })); 
      } 
      render() { 
       return <span>test</span> 
      }; 
     }; 
     // Rendering 
     const rendered = renderIntoDocument(<Component/>); 
     // Firing event 
     expect(rendered.state.key).to.equal(false); 
     // Error here 
     Simulate.keyDown(window, { keyCode: 17 }); 
     expect(rendered.state.key).to.equal(true); 
    }); 
}); 

ответ

1

Если вы настроили ваш слушатель как window.addEventListener('keydown', myFunc) то вам нужно только проверить myFunc, вы на самом деле не нужно, чтобы проверить, что addEventListener вызывает вашу функцию когда keydown.

Всегда привязывая события к функциям (а не выполняя работу в обратном вызове), тестирование более прямое (вы тестируете свой код), а также вы можете удалить прослушиватели событий, когда вы закончите с ними.

+1

насчет проверки того, что compononent будет слушать KeyDown события? Возможно, это должно быть частью спецификации. Если нет, можно удалить «addEventListener», и компонент все равно пройдет тест. – jokka

+0

Действительная точка. Лично я полагаюсь на тесты автоматизации для тех видов вещей, и пусть модульные тесты проверяют логику. –

+0

Достаточно хорошо. Это просто меня немного беспокоит, что обработчик событий в основном частный метод, и тест полагается на него. Но это не имеет большого значения. – jokka

1

Я решил это благодаря комментарию Дэвида, просто проигнорировав это событие и установив состояние на то, что мне нужно для теста. Я также узнал о другом способе тестирования событий окна в будущем. Создавая класс окна, который расширяет EventEmitter, вы можете получать события keydown/keyup, такие как ctrl через window.emit('keydown',{keyCode: 17}).

Это код моего _test_helper.js:

import jsdom from 'jsdom'; 
import chai from 'chai'; 
import EventEmitter from 'events'; 

const doc = jsdom.jsdom('<!doctype html><html><body></body></html>'); 

const windowClass = class extends EventEmitter { 
    constructor() { 
     super(doc.defaultView); 
     this.__defineSetter__('onkeydown', f => this.on('keydown', f)); 
     this.__defineSetter__('onkeyup', f => this.on('keyup', f)); 
    } 
    addEventListener (e,f) { 
     this.on(e,f); 
    } 
}; 

const win = new windowClass(); 

global.document = doc; 
global.window = win; 

Object.keys(window).forEach((key) => { 
    if (!(key in global)) { 
    global[key] = window[key]; 
    } 
});