1

まだPrototypeJSを使用していて、 jasminejasmine-prototypeプラグインを使用してカスタムイベントをテストしたい人のためにこれを投稿しています。

ユーザーのクリックまたはフォームの送信に基づいてカスタムイベントをトリガーしています。カスタムイベントが正しく発生することをテストする簡単な方法が必要でした。

次に例を示します。

var CustomEventsDispatcher = ( function() {
   function init(){

    //if elements exists
    if($$('a.trigger_bomb')) {
        // Observe the elements
        $$(elements).each(function(element) {
            element.observe('click', function(e) {
                this.fire("bomb:explode", {})
            });
        });
    }


    return {'init' : init};
 })();

Webで利用可能なリソースを使用して、フィクスチャを作成しました...

 // spec/fixtures/links.html
 <a class="trigger_bomb" href="#"> Trigger Bomb </a>

...およびテストスイート:

  //spec/trigger_bomb_spec.js
 describe("Trigger Bombs", function() {

    beforeEach(function(){
       loadFixtures("links.html")
       CustomEventsDispatcher.init();
   })

   it("should raise the custom event", function(){
      var element=$$('a.trigger_bomb').first();
      spyOnEvent(element, 'click');
      element.click();

      expect('click').toHaveBeenTriggeredOn(element);
      expect('bomb:explode').toHaveBeenTriggeredOn(element);
   });
 }); 

最初のアサーションは正常に機能しますが、2番目のアサーションは機能しません。その理由は、spyOnEventクリックイベントの処理方法を変更するためですelement

4

1 に答える 1

1

fire最も簡単な方法は、次のように関数をモックすることです。

  //spec/trigger_bomb_spec.js
 describe("Trigger Bombs", function() {

    beforeEach(function(){
       loadFixtures("links.html")
       CustomEventsDispatcher.init();
   })

   it("should raise the custom event", function(){
      var element=$$('a.trigger_bomb').first();
        spyOn(element, 'fire')
        element.click()
        expect(element.fire).toHaveBeenCalledWith('bomb:explode', {})
   });
 }); 

ただし、このソリューションには副作用があります。クリックが実行され、ジャスミンページの結果が継続的にリロードされます。beforeEachクリックイベントをインターセプトし、グローバルフックを使用してデフォルトの動作を停止する必要があります。

// spec/helpers/spec_helper.js
beforeEach(function(){

    // stop all clicks from fixtures 
    // (but allow clicks from the user in the jasmine result page)
    document.observe('click', function(e){
        var element = e.findElement('#HTMLReporter')
        if (element == document)   {
            Event.stop(e)
        }
    })             
})

これが誰かがデバッグの数時間を節約するのに役立つことを願っています:)。より良い代替案についてコメント/改善/提案してください。

于 2012-11-18T11:47:10.657 に答える