在测试JavaScript时,还有比setTimeout更好的方法来等待异步回调吗?

时间:2013-07-22 12:42:41

标签: javascript jquery sinon

鉴于此代码:

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的回调气味很糟糕,如果我做了太多的话,它会减慢我的测试套件。

但是,我觉得意图相当清晰,而且似乎确实测试了我想要的内容。

有没有更好的方法,请你解释一下你的答案中发生了什么?

3 个答案:

答案 0 :(得分:3)

传递您的匿名函数以将表单显示为参数,并在追加后在回调中调用它。为了确保它被调用,你可以使它成为一个$ .ajax请求,它也包含错误回调。

这样,当get请求完成且没有多余时间或过早调用时,就会调用它。

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

答案 1 :(得分: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);
});

答案 2 :(得分:-1)

使用$ .doTimeout插件

请查看以下文档。

http://benalman.com/projects/jquery-dotimeout-plugin/

希望这有帮助