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

时间:2013-01-10 05:50:47

标签: javascript mocking requirejs mocha

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

一切正常,直到我想使用Sinon.JS引入存根,模拟和间谍。经过大量搜索,我在test frameworks in the 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"
    };
});

但是,将代码转换为使用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"
    };
});

我做错了什么?我完全感到困惑的是,Mocha没有报告RequireJS泄漏,但是Squire.js报告泄漏。我还尝试了在另一个StackOverflow question on mocking RequireJS dependencies中找到的一些其他解决方案,例如自定义函数和testr.js,在Squire.js之前,并且有类似的结果。到目前为止,我一直无法找到一个使用Mocha,RequireJS和Sinon.JS的例子。

placed my current code base on GitHub以防有一些我遗漏的关键信息或其他内容。有问题的测试可以在test\spec\test.app.js中找到。

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

1 个答案:

答案 0 :(得分:5)

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

我的测试是通过RequireJS在require语句中加载的,如下所示

require([
  'spec/test.smoketest',
  'spec/test.app'
  ], runMocha);

其中runMocha只是一个简单地调用mocha.run()

的函数

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

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

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

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