2014-05-07 17 views
11

Ich untersuche, wie man Jasmine mit Karma benutzt. Ich versuche, einen Rahmen in meinen Controller zu injizieren und von irgendwo habe ich diesen Code abgeholt ...

var scope = { message: 'hello' }; 

beforeEach(angular.mock.module('myApp')); 

beforeEach(angular.mock.inject(function ($rootScope, $controller) { 

    scope = $rootScope.$new(); 

    $controller('myController', { $scope: scope }); 

})); 

Das Problem ist, dass der Umfang mit der Linie weggewischt wird ...

scope = $rootScope.$new(); 

So kann ich es auskommentieren, aber ich frage mich, wofür die Verwendung dieser Linie ist? Wann möchte ich $rootscope.$new() anrufen? Ich verstehe, dass es mit Isolation zu tun hat, aber ich bekomme nicht wirklich die praktischen Anwendungen davon.

UPDATE: Wie Tim unten hervorhebt, ist es ein Problem, weil ich meinen eigenen Umfang erklärt habe. So kann ich den Code ändern zu sein ....

var scope; 

beforeEach(angular.mock.module('myApp')); 

beforeEach(angular.mock.inject(function ($rootScope, $controller) { 

    scope = $rootScope.$new(); 

    scope.message = 'hello'; 

    $controller('myController', { $scope: scope }); 

})); 

Und das funktioniert mehr wie erwartet, aber ich frage mich immer noch, was der beste Ansatz? Was ist $rootscope.$new() sogar für?

+0

'Das Problem ist der Umfang mit dem line' weggewischt wird glaube, ich würde das eigentliche‚Problem‘ist, dass Sie * definiert * dein eigenes 'var scope' –

+0

Okay, das macht jetzt Sinn, sagst du. In diesem Sinne ist das der beste Ansatz? – Exitos

+0

Warum verwenden Sie nicht einfach Yeoman und lassen Sie es Ihre Jasmine/Karma-Konfiguration einrichten? – mortsahl

Antwort

3

Scopes in Winkel sind in Eltern-Kind-Beziehungen verschachtelt, die alle aus einem einzigen Elternteil Ableitung $rootScope

Dies ist, wie Winkel die $scope erzeugt, die in Ihrem Controller eingespritzt wird, so dass es die gleiche Erfahrung erstellt, wenn Sie Einheit sind Testen Regler.

Dies ist besonders nützlich, wenn Sie etwas in Ihrem Controller tun, die Sie $ apply aufrufen müssen, anstatt Sie dies auch verspotten zu müssen.

11

$rootScope.$new erstellt eine neue Instanz von $rootScope.Scope, die von $rootScope erbt. Mit anderen Worten, es erstellt einen neuen untergeordneten Gültigkeitsbereich von $rootScope.

Der Grund, warum Sie es in Tests (wie dem, das Sie gepostet haben) verwenden, ist, weil Ihre andere Alternative $rootScope selbst ist. Dies könnte zu Chaos führen, da es überall verwendet werden könnte.

Ich halte es für die beste Vorgehensweise, einen neuen Bereich für jeden Testfall zu erstellen (und danach zu zerstören).

Hier ist dein Beispiel neu geschrieben, was ich eine bewährte Methode betrachten:

describe('myModule', function() { 

    var $rootScope; 

    beforeEach(module('myModule')); 

    beforeEach(function() { 
     inject(function(_$rootScope_) { 
      $rootScope = _$rootScope_; 
     }); 
    }); 

    describe('myController', function() { 

     var $scope; 

     beforeEach(function createChildScopeForTheTest() { 
      $scope = $rootScope.$new(); 
     }); 

     afterEach(function disposeOfCreatedChildScope() { 
      $scope.$destroy(); 
     }); 

     it('tests something', function() { 
      $scope.message = 'hello'; 

      $controller('myController', { $scope: $scope }); 

      expect($scope.something).toEqual('world'); 
     }); 
    }); 
}); 
+0

Ich mag dieses Beispiel. Ein Problem jedoch, bekomme ich einen Fehler, wenn ich versuche, den Bereich in einem AfterEach-Block zu zerstören. Scheint, dass der Bereich zu diesem Zeitpunkt bereits aufgeräumt und zerstört ist. – SuneRadich

+1

Ich benutze es in allen meinen Tests, von denen ich über 10000 habe. Ich habe nie auf dieses Problem gestoßen.Möglicherweise liegt es an etwas anderem, das Sie in Ihrem Test machen. Poste etwas Code, wenn du Hilfe dabei brauchst, das zu beheben :-) – eitanfar

Verwandte Themen