2013-07-22 70 views
4

鑑於這種代碼:在測試JavaScript時,比setTimeout更好地等待asnyc回調嗎?

showForm = function (url) { 
     return $.get(url, function (html) { 
      $('body').append();    
     }); 
}; 

當使用sinon.jsjQuery.mockjax.jsexpect.js,我有以下測試通過:

it("showForm calls jQuery.append", function() { 

    $.mockjax({ 
      url: '/fake'      
    }); 

    var spy = sinon.spy($.fn, "append");    
    presenter.showForm('/fake'); 

    setTimeout(function() { 
     expect(spy.called).to.be.equal(true); 
    }, 1000); 
}); 

使用setTimeout功能等待從異步回調$.get味道不好如果我做得太多,它會減慢我的測試套件。

但是,我覺得這個意圖是相當清楚的,它似乎確實測試了我想要的。

有沒有更好的方法,你能解釋一下你的答案是怎麼回事?

+0

你可以使ajax調用async:false? –

+0

謝謝,不是在這種情況下,而不是在mockjax服務器(我可以看到) – davy

回答

3

傳遞您的匿名函數以將窗體顯示爲參數,並在追加後的回調中調用它。爲了確保它的調用,你可以使它成爲一個覆蓋錯誤回調的$ .ajax請求。

這種方式在獲取請求完成時沒有多餘的時間或調用得太早時就會被調用。

showForm = function (url, callback) { 
     return $.get(url, function (html) { 
      $('body').append(); 
      if(callback != undefined) 
      callback(); 
     }); 
}; 

it("showForm calls jQuery.append", function() { 

    $.mockjax({ 
      url: '/fake'      
    }); 

    var spy = sinon.spy($.fn, "append"); 

    presenter.showForm('/fake', function(){ 
     expect(spy.called).to.be.equal(true); 
    }); 
}); 
+0

謝謝 - 我喜歡這樣 - 我不確定的唯一的事情是添加回調只是爲了測試目的。這被認爲是良好的做法? – davy

+1

更好的是,通過測試'if(callback){callback()}'使回調可選。這樣,您不需要修改生產代碼,但仍然允許測試代碼根據需要傳遞迴調。 – slebetman

+0

@davy:爲了使代碼可測試,是的,現在通常認爲它是很好的做法。有代碼被測試的代碼比不能被測試的代碼更好,即使使代碼可測試實際上可能會降低可讀性。 – slebetman

1

您應該使用sinons fakeServer。當撥打電話$.ajax時,這將立即調用您的ajax回調。看到這個jsFiddle

before(function(){ 
    var server = sinon.fakeServer.create(); 
    server.respondWith('response'); 
}) 

it("showForm calls jQuery.append", function() { 
    var spy = sinon.spy($.fn, "append");    
    presenter.showForm('/fake'); 
    server.respond(); 
    expect(spy.called).to.be.equal(true); 
}); 
+0

謝謝,對不起安德烈亞斯,這將返回false - 我需要調查fakeServer的鏈接,除非你能發現明顯的東西? – davy

+0

Mhmm由於某些原因'autoRespond = true'在這裏不起作用,更新我的回答 –

+0

謝謝 - 我肯定會有這方面的用途。 – davy