0

我有一個控制器用於從不同的地方改變一些DOM。如何分別測試控制器?

控制器是:

angular.module('myModule').controller('myController', myController); 

function myController() { 
    this.addSomeClass = function() { 
     $('#idOfSomeElement').addClass('someClass'); 
    }; 
} 

,它是這樣使用。在不同的組件和html中。

<div id="idOfSomeElement"></div> 
. 
. 
. 
<some-angular-component-here> 
    <div ng-controller="myController as ctrl"> 
     <div ng-click="ctrl.addSomeClass()"></div> 
    </div> 
</some-angular-component-here> 
. 
. 
. 
<using-in-onother-place> 
    <div ng-controller="myController as ctrl"> 
     <div ng-click="ctrl.addSomeClass()"></div> 
    </div> 
</using-in-onother-place> 

我試着像這樣測試它,但我有未定義的CTRL。

describe('Controller test', function() { 
    'use strict'; 

    var ctrl, 
     element; 

    beforeEach(inject(function ($rootScope, $compile) { 
     var scope = $rootScope.$new(); 
     angular.element('<div id="idOfSomeElement"></div>' + 
         '<div ng-controller="myController as ctrl">' + 
          '<div id="button" ng-click="ctrl.addSomeClass()"></div>' + 
         '</div>'); 

     element = $compile(element)(scope); 
     scope.$apply(); 

     // how to get controller here with linked to html? 
     ctrl = $controller('myController'); 
     ctrl = element.controller('myController'); 

    })); 

    it('should add some class', function() { 

     var button = $(element).find('#button')[0]; 
     $(button).trigger('click'); 

     var someElement = $(element).find('#idOfSomeElement')[0]; 
     expect(someElement).toHaveSomeClass(); 
    }); 
}); 

如何正確測試這種控制器? 而且我知道在控制器內部操縱DOM是件壞事,但我需要對它進行單元測試。

感謝

+0

在測試DOM燈具從文檔中分離出來,所以'$('#idOfSomeElement')'選擇器不會到達夾具。最好的辦法是模擬'$(...)'(最有可能通過stubbing jQuery'init'方法完成,就像它顯示的[這裏](http://stackoverflow.com/a/36356692/3731501) )和'addClass'方法和間諜在他們的電話。這是爲什麼將jQuery與Angular混合是不好的原因之一。是的,這不應該在控制器中完成。 – estus

回答

0

我想你忘了angular.element的返回值分配給你的元素屬性...

element = angular.element(.... 

完整beforeEach:

beforeEach(inject(function ($rootScope, $compile) { 
    var scope = $rootScope.$new(); 
    element = angular.element('<div id="idOfSomeElement"></div>' + 
        '<div ng-controller="myController as ctrl">' + 
         '<div id="button" ng-click="ctrl.addSomeClass()"></div>' + 
        '</div>'); 

    element = $compile(element)(scope); 
    scope.$apply(); 

    // how to get controller here with linked to html? 
    ctrl = $controller('myController'); 
    ctrl = element.controller('myController'); 

})); 
+0

謝謝,我是盲人白癡) –