【问题标题】:Testing for a function that contains asynchronous code测试包含异步代码的函数
【发布时间】:2013-03-18 09:40:56
【问题描述】:

使用 qUnit,如果您的测试中有异步代码,我知道如何使用 asyncTest(),但是如果您有一个包含异步代码的函数怎么办?

换句话说,异步请求不在测试中,而只是正在测试的代码的一部分。

以这段代码为例:

function makeAjaxCall(){
    $.get('/mypage', {}, function(data){
        // Do something with `data`
    },'json');
}

如何在测试中调用makeAjaxCall(),然后在ajax 请求返回的data 上运行测试?

【问题讨论】:

    标签: javascript unit-testing asynchronous qunit


    【解决方案1】:

    在这种情况下,您可以使用jQuery Global Ajax Event Handlers。调用前绑定,测试完成后解绑,可能通过Qunit中的module方法。

    类似的东西(未经测试):

    asyncTest(function() {
      expect(1);
    
      $(document).ajaxSuccess(function(e, xhr, settings) {
         var jsonRep = JSON.parse(xhr.responseText);
         // assert on jsonRep
         //ok(true);
      });
      $(document).ajaxError(function(e) {
         ok(false);
      });
      $(document).ajaxComplete(function() {
         start();
    
         $(document).unbind('ajaxSuccess ajaxError ajaxComplete');
      });
    
      makeAjaxCall();
    });
    

    请注意全局处理程序do not have access to the parsed contents,您必须自己使用 JSON.parse 重新解析它们。不理想,但我不知道其他方法。

    【讨论】:

    • 这个答案似乎应该可行,但如果异步事件不是 ajax 请求怎么办?我唯一的选择是从回调中手动触发事件吗?
    • 我想是的。您需要在异步过程中加入某种钩子并确定它已完成。我不知道有任何 JavaScript 构造可以为每种类型的异步操作执行此操作。显然,您可以通过覆盖实现并在幕后做一些魔术来为 window.setTimeout 等众所周知的实例创建自己的实例,但可以说更容易进行回调。 $.Deferred 有助于使实现更干净。
    【解决方案2】:

    似乎没人关心mockAjax,所以这几天我找到了更好的东西:sinonJS! 你知道这个名为 Fiddler 的奇妙工具的自动响应功能吗? sinonJS 允许你在客户端做同样的事情,它是一种 ajax 旁路代理。 如果您有兴趣查看示例,请告诉我...所以 sinonJS 可以在不访问服务器的情况下响应任何 ajax 请求,如果您想模拟您的客户端,这是一种魔法,如果您愿意对您的 javascript 代码进行单元测试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-11
      • 2012-11-25
      • 1970-01-01
      • 2020-09-18
      • 2012-10-28
      相关资源
      最近更新 更多