我有一个要测试的AMD模块,但我想模拟其依赖关系,而不是加载实际的依赖关系。我正在使用requirejs,模块的代码如下所示:

define(['hurp', 'durp'], function(Hurp, Durp) {
  return {
    foo: function () {
      console.log(Hurp.beans)
    },
    bar: function () {
      console.log(Durp.beans)
    }
  }
}

如何模拟出hurpdurp,以便可以有效地进行单元测试?

最佳答案

因此,在阅读this post之后,我想出了一个使用requirejs config函数为您的测试创建新上下文的解决方案,您可以在其中轻松模拟依赖项:

var cnt = 0;
function createContext(stubs) {
  cnt++;
  var map = {};

  var i18n = stubs.i18n;
  stubs.i18n = {
    load: sinon.spy(function(name, req, onLoad) {
      onLoad(i18n);
    })
  };

  _.each(stubs, function(value, key) {
    var stubName = 'stub' + key + cnt;

    map[key] = stubName;

    define(stubName, function() {
      return value;
    });
  });

  return require.config({
    context: "context_" + cnt,
    map: {
      "*": map
    },
    baseUrl: 'js/cfe/app/'
  });
}

因此,它将创建一个新的上下文,其中HurpDurp的定义将由您传递给函数的对象设置。该名称的Math.random可能有点脏,但是可以工作。因为如果要进行大量测试,则需要为每个套件创建新的上下文,以防止重用您的模拟,或者在需要真正的requirejs模块时加载模拟。

在您的情况下,它看起来像这样:
(function () {

  var stubs =  {
    hurp: 'hurp',
    durp: 'durp'
  };
  var context = createContext(stubs);

  context(['yourModuleName'], function (yourModule) {

    //your normal jasmine test starts here

    describe("yourModuleName", function () {
      it('should log', function(){
         spyOn(console, 'log');
         yourModule.foo();

         expect(console.log).toHasBeenCalledWith('hurp');
      })
    });
  });
})();

因此,我在生产中使用这种方法已有一段时间,并且它确实很可靠。

09-30 16:41
查看更多