简体   繁体   English

如何使用squire模拟内联requirejs依赖项以进行单元测试?

[英]How to mock inline requirejs dependencies with squire for unit testing?

I'm using requirejs with inline requires, for instance: 我正在将requirejs与内联需求一起使用,例如:

define(['someDep'], function(someDep) {
  return {
    someFn: function() {
      require(['anotherDep'], function(anotherDep) {
        anotherDep.anotherFn();
      });
    }
  } 
});

In my particular case, I cannot include anotherDep in the define. 在我的情况下,我不能在定义中包含anotherDep

When testing with mocha, I have a test case like this: 使用Mocha进行测试时,我有一个这样的测试用例:

define(['squire'], function(Squire) {
  var squire = new Squire();
  describe('testcase', function() {
    it('should mock anotherDep', function(done) {
      var spy = sinon.spy();
      squire.mock('anotherDep', {
        anotherFn: spy
      });
      squire.require(['someDep'], function(someDep) {
        someDep.someFn();
        expect(spy).to.have.been.calledOnce;
        done();
      });
    });
  });
});

fails because anotherDep calls require directly and not squire.require . 失败,因为anotherDep调用直接require而不是squire.require The work-around is to replace require in the global scope, 解决方法是在全球范围内替换require

var originalRequire;

before(function() {
  originalRequire = require;
  require = _.bind(squire.require, squire);
});

after(function() {
  require = originalRequire;
});

This works (note that squire.require must be bound to the squire object in some way, I'm using underscore to do this) except that the spy will still not be called because of timing. 这行得通(请注意, squire.require必须以某种方式绑定到squire对象,我正在使用下划线执行此操作),但由于时间安排,间谍将不会被调用。 The test also has to change to 测试也必须更改为

it('should mock anotherDep', function(done) {
  squire.mock('anotherDep', {
    anotherFn: function() {
      done();
    }
  });
  squire.require(['someDep'], function(someDep) {
    someDep.someFn();
  });
});

Is there a better way? 有没有更好的办法? If not, hope this provides a solution for others running into the same problem. 如果不是,希望这为遇到相同问题的其他人提供了解决方案。

I've not tried to do specifically what you are trying to do but it seems to me that if squire is doing a thorough job, then requiring the require module should give you what you want without having to mess with the global require . 我没有尝试专门做您想做的事情,但是在我看来,如果squire做得很周到,那么require模块将为您提供所需的内容,而不必与全局require The require module is a special (and reserved) module that makes available a local require function. require模块是一个特殊的(保留的)模块,它提供了本地require函数。 It is necessary for instance when you use the Common JS syntactic sugar. 例如,当您使用Common JS语法糖时,这是必需的。 However, you can use it whenever you desire to get a local require . 但是,无论何时require本地require ,都可以使用它。 Again, if squire does a thorough job, then the require it gives you should be one that squire controls rather than some sort of pristine require . 同样,如果squire做得很周到,那么它给您的require应该是squire控件的要求,而不是某种原始的require

So: 所以:

define(['require', 'someDep'], function (require, someDep) {
  return {
    someFn: function() {
      require(['anotherDep'], function(anotherDep) {
        anotherDep.anotherFn();
      });
    }
  } 
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM