2014-01-17 170 views
1

我正在使用AngularJS應用程序。我希望能夠通過這個應用程序實現單元測試。目前,我正在爲單元測試我的一個指令而苦苦掙扎。在這個時候,我有一個模塊的設置如下:在AngularJS中有一個控制器的單元測試指令

angular.module('my.module', []) 
    .controller('myCtrl', function ($scope, $element) { 
    // Directive specific business logic goes here 
    }) 
    .directive('myDirective', function() { 
    return { 
     restrict: 'E', 
     transclude: true, 
     replace: true, 
     scope: { 
     title:'=', 
    state:'@' 
     }, 
     templateUrl: 'myHtml.tpl.html', 
     controller: myCtrl 
    }; 
    }) 
; 

我已經出離我的指令分割我的控制器,因爲我需要能夠進行單元測試控制器。此代碼在應用程序中工作。但是,當我嘗試進行單元測試時遇到問題。我遇到了問題,因爲我無法弄清楚如何從單元測試中將$元素注入控制器。目前,我有以下測試設置:

describe('my.module', function() { 
    var $scope; 
    var myCtrl; 

    beforeEach(module('myApp')); 
    beforeEach(inject(function ($controller, $rootScope, $element) { 
     $scope = $rootScope.$new(); 
     myCtrl = $controller('myCtrl', { $scope: $scope }); 
    })); 

    it('should create controller', inject(function() { 
     expect(testCtrl).toBeDefined(); 
    })); 

    it('should create the directive', inject(function ($rootScope, $compile, $log) { 
     var d = angular.element('<my-directive></my-directive>'); 
     $compile(d)($rootScope); 
     $scope.$digest(); 

     expect($log.assertEmpty).not.toThrow(); 
    })); 
}); 

$ element是自動注入指令的東西。但是,我無法弄清楚如何將其注入控制器。我需要這樣做,以便我可以進行單元測試。我該怎麼做呢?

謝謝!

回答

1

用於注射$element$log做,因爲它:

describe('my.module', function ($compile) { 
    var $scope, $controller, $element, $log, $compile, html; 

    beforeEach(module('myApp')); 
    // an another module ... 

    beforeEach(inject(function ($injector) { 
     $scope = $injector.get('$rootScope'); 
     $controller = $injector.get('$controller'); 
     $element = $injector.get('$element'); 
     $log = $injector.get('$log'); 
     $compile = $injector.get('$compile'); 

     function createController(){ 
      return $controller('MyCtrl', {'$scope' : $scope, '$element' : $element, '$log': $log }); 
     } 
     // init your controller 
     createController(); 

    })); 

    it('should create the directive',function() { 
    // possibility to use $scope, $element, $log in your test 
     $compile('<my-directive></my-directive>')($scope); 
     $scope.$digest(); 

     expect($log.assertEmpty).not.toThrow(); 
    }); 
}); 
+0

當我嘗試你已經顯示的方法時,我收到一個錯誤:'未知的提供者:$ elementProvider < - $ element'。你有沒有可能試試我的小提琴?對於我的生活,我無法弄清楚這一點。 – user2871401

+0

$元素是你的控制器的一個參數,我只是拿起了我見過的代碼,但顯然它沒有被使用,所以你可以刪除注入器和函數createController。 – Snoozer

+0

兩種注入$元素的方法都是相等的...... –

2

我可以在控制器的單元測試建議是隻擔心控制器暴露的邏輯。您正試圖在控制器測試中測試指令的邏輯,即通過$element

在控制器測試中模擬這一點,因爲元素可以是任何東西。你的控制器不應該關心DOM;它是一個控制器,它的主要工作(可能只是)創建一個範圍,並將「事物」暴露給範圍 - 函數,變量,邏輯。它們不應該受限於指令的邏輯,否則耦合太緊。控制器應該能夠自由地接收輸入,正確的輸入,即,並且使用輸入來回饋輸出。

如果你可以舉一個你的控制器公開的邏輯的例子,那麼我可以進一步幫助組成單元測試。

更新:

現在看看你提供的單元測試。您需要將邏輯從控制器和指令的單元測試中分離出來。