在sinon中存根一个依赖函数

时间:2015-03-24 00:15:18

标签: javascript unit-testing amd sinon intern

我使用实习生作为测试框架和sinon来模拟数据。我不想在单元测试期间点击服务器获取http请求。所以我创建了一个模块,它返回deferred.promise中的数据,如下所示:

define(["require", ..], function(require, ...) {
  function fakerequest(){
    dfd = new Deferred();
    setTimeout(function(){
      deferred.resolve(data);
    },100);
    return dfd.promise;
  }
  return fakerequest;
});

这是使用http请求命中外部服务器的原始AMD请求模块:

define(["require", ..], function(require, ...) {
  function request(){
    dfd = new Deferred();
    ... 
    return dfd;
  }
  return request;
});

这是我想测试的模块。并且它对某些数据使用请求函数:

define(["require", ..], function(require, ...) {
  var QuerySomething = {
    execute: function(){
      ...
      return request();
    };
  }
  return QuerySomething;
});

现在我想测试QuerySomething模块,但我不希望它使用原始请求函数,而是使用fakeRequest函数。因此,在我的实习测试中,我使用sinon将原始请求与伪造的请求存根。

registerSuite({
  name: 'QuerySomething',

  setup: function(){
    stub = sinon.stub(request, "request", fakeRequest);
  },

  teardown: function () {
    stub.restore();
  },

execute: function(){
  queryTask.execute(query).then(function(results){
    console.log(results);
  });
}

但是我收到了这个错误:

TypeError: Attempted to wrap undefined property request as function

有人可以让我知道如何模拟依赖函数吗?

1 个答案:

答案 0 :(得分:1)

Sinon不能直接存根AMD依赖。当它存根对象方法时,它用新方法替换对象上的方法。假设您有一个对象foo,其方法为barbarfoo上的属性。您的代码会在某个时刻调用foo.bar()

现在您存根bar方法。 bar上的属性foo被修改为指向新函数(存根)。当您的代码现在调用foo.bar()时,实际执行存根,因为foo.bar指向存根而不是原始函数。

使用AMD模拟类似您的请求模块的标准方法是to use a loader map。使用加载程序映射,您可以将QuerySomething模块配置为在测试期间将伪请求模块作为依赖项而不是真实的模块加载。