2016-08-05 10 views
6

私が書いているコンポーネントは、ctrlが押されたかどうかによって動作を変更する必要があります。Reactjsのテストウィンドウキーダウンイベント

私はwindow.onkeydownイベントを使用しますが、からSimulateテストUtilsのは私がwindowに対してイベントを送出することはできません反応します。私もwindow.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 17 }));を試しましたが、mocha/nodeはKeyboardEventを認識しません。

試験方法はありますかを使用してください。React Test Utils?もしそうでなければ、ノードのためのモカでそれを行うより良い方法はありますか?ここで

は、問題を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の時に、あなたの関数を呼び出すことをテストする必要はありません。​​が発生します。

(コールバックで作業するのではなく)常にイベントを関数にバインドすることで、テストはより直接的です(コードをテストしています)。また、イベントリスナーを終了すると削除できます。

+1

何compononentは、KeyDownイベントイベントを監視すべきであるという事実をテストについて:

これは私の _test_helper.jsのコードですか?多分それは仕様の一部でなければなりません。そうでなければ、 'addEventListener'を取り除くことができ、コンポーネントは引き続きテストに合格します。 – jokka

+0

有効なポイント。個人的に私はこれらの種類の自動化テストに頼り、単体テストでロジックをテストさせます。 –

+0

十分です。イベントハンドラは基本的にプライベートメソッドであり、テストはそのメソッドに依存しているだけです。しかしそれは大きな問題ではない。 – jokka

1

私はDavidのコメントのおかげで、イベントを無視し、テストに必要な状態に状態を設定するだけで解決しました。私はまた、将来的にウィンドウイベントをテストする別の方法を発見しました。 EventEmitterを拡張するウィンドウクラスを作成すると、ctrlからwindow.emit('keydown',{keyCode: 17})のようなkeydown/keyupイベントを受け取ることができます。

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]; 
    } 
});