7

我正在使用 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"
    };
});

但是,如下转换代码以使用 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。我还尝试了在 Squire.js 之前在另一个StackOverflow 问题中找到的关于模拟 RequireJS 依赖项的其他一些解决方案,例如自定义函数和 testr.js,并且得到了类似的结果。迄今为止,我一直无法找到同时使用 Mocha、RequireJS 和 Sinon.JS 的示例。

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

非常感谢任何帮助。我非常想摆脱对我的测试设置的胡思乱想,然后真正开始使用我的应用程序。提前致谢。

4

1 回答 1

5

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

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

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

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

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

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

现在我了解了发生了什么并且这是意料之中的,我很乐意将 Mocha 配置为允许这些全局对象。这可以在 Mocha 配置中完成,如下所示:

mocha.setup({
    ui: "bdd",
    globals:["_", "$", "jQuery", "Backbone", "Marionette"]
});
于 2013-01-11T02:39:18.140 回答