在使用带有RequireJS和Mocha的Squire.js时,如何避免引入全局泄漏?

Tre*_* A. 7 javascript mocking mocha.js requirejs

我正在使用Backbone和Backbone.Marionette编写单页JavaScript应用程序.我使用AMD模块和RequireJS来帮助组织我的代码和管理依赖项.我也使用Mocha作为我的TDD/BDD测试框架.

一切都工作正常,直到我想使用Sinon.JS引入存根,模拟和间谍.经过大量的搜索,我在RequireJS wikiSquire.js中看到了一个关于测试框架的页面,看起来它很适合我的需求.但是,当我尝试使用Squire.js加载模块时,Mocha突然报告模块依赖关系的全局泄漏.如果我使用Require.JS直接加载模块,则不会报告泄漏.

例如,以下测试代码不会导致Mocha报告任何泄漏:

define(['app/app'], function(app) {
    describe('App', function() {
        it('Should define a \'header\' region', function() {
            expect(app.headerRegion).to.exist;
        });

        it('Should define a \'main\' region', function() {
            expect(app.mainRegion).to.exist;
        });
    });

    return {
        name: "App"
    };
});
Run Code Online (Sandbox Code Playgroud)

但是,将代码转换为使用Squire.js如下导致Mocha报告jQuery,Backbone和Marionette的泄漏(app.js的依赖关系):

define(['Squire'], function(Squire) {
    describe('App', function() {

        var testContext = {};

        beforeEach(function(done) {
            testContext.injector = new Squire();
            testContext.injector.require(['app/app'], function(app) {
                testContext.app = app;
                done();
            });
        });

        it('Should define a \'header\' region', function() {
            expect(testContext.app.headerRegion).to.exist;
        });

        it('Should define a \'main\' region', function() {
            expect(testContext.app.mainRegion).to.exist;
        });
    });

    return {
        name: "App"
    };
});
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?我完全感到困惑的是,Mocha并没有报告RequireJS的漏洞,而是报告了Squire.js.我还尝试了另一个我在另一个StackOverflow问题中发现的其他解决方案,它们在Squire.js之前模拟了RequireJS依赖项,例如自定义函数和testr.js,并且有类似的结果.到目前为止,我一直无法找到一个使用Mocha,RequireJS和Sinon.JS的示例.

我已将我当前的代码库放在GitHub上,以防有一些我遗漏的关键信息或其他内容.有问题的测试可以在test\spec\test.app.js中找到.

非常感谢任何帮助.我非常希望能够通过我的测试设置来解决问题并实际开发我的应用程序.提前致谢.

Tre*_* A. 5

在进一步思考之后,我意识到这实际上是预期的行为以及app.js加载测试时间的副作用.

我的测试是通过RequireJS在require下面的语句中加载的

require([
  'spec/test.smoketest',
  'spec/test.app'
  ], runMocha);
Run Code Online (Sandbox Code Playgroud)

where runMocha只是一个简单调用的函数mocha.run().

在我看来,Mocha最有可能检测到全局泄漏的方式是比较每次测试运行前后全局注册的内容.在上面的第一个示例中,未报告泄漏,jQuery,Backbone和Marionette由RequireJS加载,然后在加载test.app.js模块时调用mocha.run().另一方面,jQuery,Backbone和Marionette在第二个示例中作为测试本身的一部分加载.

因此,第一个配置不会报告任何泄漏,因为jQuery,Backbone和Marionette mocha.run()调用之前已经全局注册.第二个配置报告泄漏,因为它们是测试期间注册的.

既然我明白了发生了什么,并且这是预期的,我很乐意配置Mocha来允许这些全局对象.这可以在Mocha配置中完成,如下所示:

mocha.setup({
    ui: "bdd",
    globals:["_", "$", "jQuery", "Backbone", "Marionette"]
});
Run Code Online (Sandbox Code Playgroud)