2013-01-10 9 views
7

Ich schreibe eine einzelne Seite JavaScript-Anwendung mit Backbone und Backbone.Marionette. Ich verwende AMD-Module und RequireJS, um meinen Code zu organisieren und Abhängigkeiten zu verwalten. Ich verwende auch Mocha als mein Test-Framework für TDD/BDD.Wie vermeide ich die Einführung globaler Lecks bei der Verwendung von Squire.js mit RequireJS und Mocha?

Alles funktionierte gut, bis ich mit Sinon.JS Stubs, Mocks und Spione einführen wollte. Nach langem Suchen stieß ich auf eine Seite auf test frameworks in the RequireJS wiki und Squire.js, die schien, als würde es meinen Bedürfnissen gut entsprechen. Wenn ich jedoch versuche, Squire.js zum Laden eines Moduls zu verwenden, meldet Mocha plötzlich globale Lecks für die Abhängigkeiten des Moduls. Es werden keine Lecks gemeldet, wenn ich das Modul direkt mit Require.JS lade.

Zum Beispiel die folgenden Testcode Mocha verursacht keine Lecks zu berichten:

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" 
    }; 
}); 

jedoch den Code Umwandlung Squire.js wie folgt zu verwenden verursacht Mocha Lecks für jQuery, Backbone zu berichten und Marionette (Abhängigkeiten von 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" 
    }; 
}); 

Was mache ich falsch? Ich bin total verblüfft, dass Mocha mit RequireJS kein Leck meldet, aber mit Squire.js. Ich habe auch einige der anderen Lösungen, die ich in einem anderen StackOverflow question on mocking RequireJS dependencies, wie die benutzerdefinierte Funktion und testr.js, vor Squire.js gefunden und hatte ähnliche Ergebnisse. Bis heute konnte ich kein Beispiel finden, das Mocha, RequireJS und Sinon.JS alle zusammen verwendet.

Ich habe placed my current code base on GitHub für den Fall, dass es einige wichtige Informationen gibt, die ich weggelassen habe oder so. Der fragliche Test kann in test\spec\test.app.js gefunden werden.

Jede Hilfe wird sehr geschätzt. Ich möchte sehr gerne mit meinem Test-Setup fertig werden und an meiner App arbeiten. Danke im Voraus.

Antwort

5

Nachdem ich dies weiter durchgespielt habe, realisierte ich, dass dies tatsächlich erwartetes Verhalten ist und ein Nebeneffekt des Zeitpunkts, zu dem app.js zum Testen geladen wird.

Meine Tests werden über RequireJS in einer require Erklärung unten

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

gezeigt geladen, wo runMocha einfach eine Funktion ist, die einfach mocha.run() nennt.

Es ist mir aufgefallen, dass die Art und Weise, wie Mocha höchstwahrscheinlich globale Lecks entdeckt, darin besteht, zu vergleichen, was global vor und nach jedem Test registriert ist. Im ersten Beispiel oben, in dem keine Lecks gemeldet werden, werden jQuery, Backbone und Marionette von RequireJS geladen, bevor mocha.run() als Teil des Ladens des Moduls test.app.js aufgerufen wird. Auf der anderen Seite werden jQuery, Backbone und Marionette im zweiten Beispiel als Teil der Tests selbst geladen.

So die erste Konfiguration meldet keine Lecks, da jQuery, Backbone und Marionette bereits global vormocha.run() genannt werden. Die zweite Konfiguration meldet Lecks, weil sie während während die Tests registriert sind.

Jetzt, da ich verstehe, was vor sich geht und das erwartet wird, kann ich Mocha konfigurieren, um diese globalen Objekte zuzulassen.Dies kann in der Mocha-Konfiguration wie folgt erfolgen:

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