2015-09-25 10 views
6

Ich versuche Unit Test für meine Events in Controller zu schreiben.

Unten ist mein Controller

myApp.controller('ParentCtrl', ['$scope', function ($scope) { 
    $scope.message = "Some text in parent"; 
    $scope.$on("update_parent_controller", function(event, message){ 
     $scope.message = message; 
    }); 

}]) 
.controller('ChildCtrl', ['$scope', function ($scope) { 
    $scope.clickFunction = function() { 
    $scope.message = "Parent updated from child controller"; 

     $scope.$emit('update_parent_controller', $scope.message); 
    } 

}]); 

Und unten ist mein Test, der i

describe("Hello Controller Test", function() { 
    var ctrl, scope; 

    beforeEach(module("myApp")); 

    beforeEach(inject(function ($controller, $rootScope) { 
     scope = $rootScope.$new(); 
     spyOn(scope, '$on'); 

     ctrl = $controller("ParentCtrl", { 
      $scope : scope 
     }); 
    })); 

    it('should change ParentCtrl message property from child ctrl', function(){ 

     var new_hero = 'Ralf ninja turtle', 
      sub_scope = scope.$new(); 

     sub_scope.$emit('update_parent_controller', new_hero); 

     expect(scope.$on).toHaveBeenCalled(); 
     expect(scope.message).toBe('Ralf ninja turtle'); //Getting err here 
    }); 
}); 

I Nachricht aktualisiert in der übergeordneten Steuerung zu erwarte schreiben versuche, Aber der Test ist versagt bei expect (scope.message) .toBe ('Ralf ninja turtle');

Antwort

0

Im Testfall wurde scope.$on ausgespäht.

spyOn(scope, '$on'); 

Um die tatsächliche Funktion aufzurufen, .and.callThrough() muss hinzugefügt werden.

spyOn(scope, '$on').and.callThrough(); 

Hier ist ein voll funktionierendes Beispiel:

angular.module('myApp', []).controller('ParentCtrl', ['$scope', function ($scope) { 
 
    $scope.message = "Some text in parent"; 
 
    $scope.$on("update_parent_controller", function(event, message){ 
 
     $scope.message = message; 
 
    }); 
 
}]); 
 

 
describe("Hello Controller Test", function() { 
 
    var ctrl, scope; 
 

 
    beforeEach(module("myApp")); 
 

 
    beforeEach(inject(function ($controller, $rootScope) { 
 
     scope = $rootScope.$new(); 
 
     spyOn(scope, '$on').and.callThrough(); // <-- This is the fix 
 

 
     ctrl = $controller("ParentCtrl", { 
 
      $scope : scope 
 
     }); 
 
    })); 
 

 
    it('should change ParentCtrl message property from child ctrl', function(){ 
 

 
     var new_hero = 'Ralf ninja turtle', 
 
      sub_scope = scope.$new(); 
 

 
     sub_scope.$emit('update_parent_controller', new_hero); 
 

 
     expect(scope.$on).toHaveBeenCalled(); 
 
     expect(scope.message).toBe('Ralf ninja turtle'); //Getting err here 
 
    }); 
 
});
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.4/jasmine.css"> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.4/jasmine.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.4/jasmine-html.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.4/boot.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular-mocks.js"></script>

1

Sie müssen $scope.$apply() nach dem Anruf an $emit anrufen. Dies würde automatisch in der Anwendung passieren, muss aber explizit im Test aufgerufen werden.

Verwandte Themen