使用sinon.stub对$ .ajax的响应进行存根,同时保持延迟功能(使用mocha + testem)

时间:2013-08-21 15:01:56

标签: javascript mocha sinon

我有使用延迟对象的代码,该对象立即从对$ .ajax的调用返回。我需要为这段代码编写单元测试,所以我不想对服务器进行实际的往返。

我可以存根jQuery并告诉存根返回我用于测试的JSON,但这会破坏代码,因为它期望一个延迟对象最终通过JSON响应而不是直接JSON响应来解析。

我的解决方案尝试是将$ .ajax存根并告诉它返回一个立即执行的函数。在这个IEFE中,我创建了一个新的$ .Deferred并设置了几毫秒的超时。超时后,我用我想要的JSON解析$ .Deferred。代码如下所示:

  stubbedAjax = sinon.stub jQuery, 'ajax'

  stubbedAjax.returns ( ->
    deferred = jQuery.Deferred()
    setTimeout ->
      deferred.resolve(JSON.stringify(customActionResponse))
    , 10
    return deferred
  )()

(此coffeescript评估以下JS:)

var stubbedAjax;

stubbedAjax = sinon.stub(jQuery, 'ajax');

stubbedAjax.returns((function() {
  var deferred;
  deferred = jQuery.Deferred();
  setTimeout(function() {
    return deferred.resolve(JSON.stringify(customActionResponse));
  }, 10);
  return deferred;
})());

当我运行我的测试(使用mocha和testem)时,我收到以下错误:

Uncaught TypeError: Cannot call method 'resolve' of undefined

我不明白为什么。在函数定义时创建引用。 setTimeout在创建延迟对象的范围内定义,因此它可以访问它。在setTimeout中放置一些console.log可以清楚地显示延迟对象是否已正确创建并可访问。

有没有人知道为什么说延迟是未定义的?或者也许是一个替代解决方案,如何在jQuery ajax响应的同时使其立即返回一个延迟对象?

提前致谢。

1 个答案:

答案 0 :(得分:2)

无法在代码中发现错误,这个简单的事件fiddle表明它应该有效。

但是在sinon中有一种更简单的方法,然后将$.ajax缩短。只需使用fake server

即可