7

Backbone と Backbone.Marionette を使用して単一ページの JavaScript アプリケーションを作成しています。AMD モジュールと RequireJS を使用して、コードを整理し、依存関係を管理しています。また、TDD/BDD のテスト フレームワークとしてMochaを使用しています。

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 の前にカスタム関数や testr.js など、RequireJS の依存関係のモックに関する別の StackOverflow の質問で見つけた他のソリューションもいくつか試してみましたが、同様の結果が得られました。今日まで、Mocha、RequireJS、および Sinon.JS をすべて一緒に使用する例を見つけることができませんでした。

省略した重要な情報などがある場合に備えて、現在のコード ベースを GitHub に配置しました。問題のテストはtest\spec\test.app.jsにあります。

どんな支援も大歓迎です。私は、テスト セットアップでモンキーを乗り越えて、実際に自分のアプリの作業に取り掛かりたいと思っています。前もって感謝します。

4

1 に答える 1

5

app.jsこれをさらに考えた後、これは実際には予期された動作であり、テストのために読み込まれるタイミングの副作用であることに気付きました。

require私のテストは、以下に示すステートメントで RequireJS を介して読み込まれます

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

whererunMochaは単に を呼び出すだけの関数ですmocha.run()

Mocha がグローバル リークを検出する可能性が最も高い方法は、各テストの実行前と実行後にグローバルに登録されているものを比較することだと思いました。リークが報告されていない上記の最初の例では、モジュールのロードの一部として mocha.run() が呼び出される前に、jQuery、Backbone、および Marionette が RequireJS によってロードされtest.app.jsます。一方、2 番目の例では、jQuery、Backbone、および Marionette がテスト自体の一部として読み込まれます。

したがって、jQuery、Backbone、Marionette はが呼び出される前に すでにグローバルに登録されているため、最初の構成ではリークは報告されません。2 番目の構成では、リークがテストmocha.run()に登録されるため、リークが報告されます。

何が起こっているのか、そしてこれが予想されることを理解したので、これらのグローバル オブジェクトを許可するように Mocha を構成することに問題はありません。これは、以下に示すように Mocha 構成で実行できます。

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