2013-10-08 18 views
29

Ich richte meine SpecRunner.html/.js, RequireConfig.js, meine Pfade und meine Shims genau so ein, wie ich es mit früheren Release-Kandidaten von Jasmine + RequireJs gemacht habe, aber jetzt zeigen meine Testmethoden Jasmine undefined. Sie haben kürzlich eine andere Methode zum Laden von Jasmine gewählt, von der ich weiß, dass sie nicht mit RequireJs kompatibel ist.Funktioniert Jasmine 2.0 wirklich nicht mit require.js?

Ist mein Verständnis korrekt? Wenn ja, können wir Jasmine + RequireJs jemals wieder verwenden?

Antwort

68

Die neue boot.js führt eine Reihe von Initialisierungen durch und hängt sie an window.onload() an, das bereits aufgerufen wurde, als require.js Jasmine lädt. Sie können window.onload() manuell aufrufen, um den HTML Reporter zu initialisieren und die Umgebung auszuführen.

SpecRunner.html

<!doctype html> 
<html> 
    <head> 
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
    <title>Jasmine Spec Runner v2.0.0</title> 

    <link rel="shortcut icon" type="image/png" href="lib/jasmine-2.0.0/jasmine_favicon.png"> 
    <link rel="stylesheet" type="text/css" href="lib/jasmine-2.0.0/jasmine.css"> 

    <!-- specRunner.js runs all of the tests --> 
    <script data-main="specRunner" src="../bower_components/requirejs/require.js"></script> 
    </head> 
    <body> 
    </body> 
</html> 

specRunner.js

(function() { 
    'use strict'; 

    // Configure RequireJS to shim Jasmine 
    require.config({ 
    baseUrl: '..', 
    paths: { 
     'jasmine': 'tests/lib/jasmine-2.0.0/jasmine', 
     'jasmine-html': 'tests/lib/jasmine-2.0.0/jasmine-html', 
     'boot': 'tests/lib/jasmine-2.0.0/boot' 
    }, 
    shim: { 
     'jasmine': { 
     exports: 'window.jasmineRequire' 
     }, 
     'jasmine-html': { 
     deps: ['jasmine'], 
     exports: 'window.jasmineRequire' 
     }, 
     'boot': { 
     deps: ['jasmine', 'jasmine-html'], 
     exports: 'window.jasmineRequire' 
     } 
    } 
    }); 

    // Define all of your specs here. These are RequireJS modules. 
    var specs = [ 
    'tests/spec/routerSpec' 
    ]; 

    // Load Jasmine - This will still create all of the normal Jasmine browser globals unless `boot.js` is re-written to use the 
    // AMD or UMD specs. `boot.js` will do a bunch of configuration and attach it's initializers to `window.onload()`. Because 
    // we are using RequireJS `window.onload()` has already been triggered so we have to manually call it again. This will 
    // initialize the HTML Reporter and execute the environment. 
    require(['boot'], function() { 

    // Load the specs 
    require(specs, function() { 

     // Initialize the HTML Reporter and execute the environment (setup by `boot.js`) 
     window.onload(); 
    }); 
    }); 
})(); 

Beispiel spec

define(['router'], function(router) { 
    'use strict'; 

    describe('router', function() { 
    it('should have routes defined', function() { 
     router.config({}); 
     expect(router.routes).toBeTruthy(); 
    }); 
    }); 
}); 
+0

Vielen Dank für diese Antwort. Ich habe einen Nachmittag damit verbracht, das zu schaffen. – keepitreal

+0

Ich bin gerade darüber gestolpert und es funktioniert super! Ich habe es sogar an eine Ansicht angehängt, indem ich die Datei "boot.js" geändert habe und sie in das div meiner Wahl geladen habe. – Josh

+1

Alter, vielen Dank! Ich habe für immer getüftelt und das hat mich sofort angefangen. – medoingthings

13

Hier ist ein alternativer Ansatz, der in einigen Fällen einfacher sein kann - Jasmine's asynchronous support verwenden, um zu laden Sie Ihre AMD-Modul vor dem Ausführen von Tests, wie folgt:

in MySpec.js:

describe('A suite', function() { 
    var myModule; 

    // Use require.js to fetch the module 
    it("should load the AMD module", function(done) { 
    require(['myModule'], function (loadedModule) { 
     myModule = loadedModule; 
     done(); 
    }); 
    }); 

    //run tests that use the myModule object 
    it("can access the AMD module", function() { 
    expect(myModule.speak()).toBe("hello"); 
    }); 
}); 

Damit dies funktioniert, müssen Sie require.js in Ihrem SpecRunner.html und möglicherweise configure require (wie gewohnt schließen z.B. durch die baseUrl Einstellung), wie folgt aus:

in SpecRunner.html:

<!DOCTYPE HTML> 
<html> 
    <head> 
    <meta charset="UTF-8"> 
    <title>Jasmine Spec Runner v2.0.0</title> 

    <link rel="shortcut icon" type="image/png" href="lib/jasmine-2.0.0/jasmine_favicon.png"> 
    <link rel="stylesheet" type="text/css" href="lib/jasmine-2.0.0/jasmine.css"> 

    <script src="lib/require.min.js"></script> 
    <script> require.config({ baseUrl: "src" }); </script> 

    <script src="lib/jasmine-2.0.0/jasmine.js"></script> 
    <script src="lib/jasmine-2.0.0/jasmine-html.js"></script> 
    <script src="lib/jasmine-2.0.0/boot.js"></script> 

    <script src="spec/MySpec.js"></script> 

    </head> 
    <body> 
    </body> 
</html> 

Für dieses Beispiel könnte die AMD-Modul Implementierung in etwa so aussehen:

in src/MyModule .js:

define([], function() { 
    return { 
    speak: function() { 
     return "hello"; 
    } 
    }; 
}); 

Hier ist ein working Plunk that implements this complete example.

Viel Spaß!

+0

Ihr Plunker ist ein Juwel! Danke – HockeyJ

+1

Alternativ können Sie auch done() in der beforeEach() -Funktion verwenden, so dass es vor jeder Spezifikation ausgeführt wird. Dann können Sie jede Spezifikation separat ausführen, ohne dass die Modulladespezifikation ausgeführt werden muss. –

Verwandte Themen