2013-07-12 36 views
18

我想用Karma和Jasmine測試一個指令來做一些事情。首先是它使用了templateUrl,其次它定義了一個控制器。這可能不是正確的術語,但它在聲明中創建了一個控制器。 Angular應用程序的設置使每個單元都包含在其自己的模塊中。例如,所有指令都包含在模塊app.directive中,所有控制器都包含在app.controller中,並且所有服務都包含在app.service中。單元測試在AngularJS中定義一個控制器的指令

使事情複雜化,控制器在此指令中定義一個依賴項,它包含一個函數,它使$ http請求在$ scope上設置一個值。我知道我可以使用$ httpBackend mock模擬這個依賴項來模擬$ http調用,並將適當的對象返回給此函數的調用。我已經在我創建的其他單元測試上做過這麼多次了,並且對這個概念有很好的把握。

下面的代碼是用CoffeeScript編寫的。

這裏是我的指令:

angular.module('app.directive') 
     .directive 'exampleDirective', [() -> 
     restrict: 'A' 
     templateUrl: 'partials/view.html' 
     scope: true 
     controller: ['$scope', 'Service', ($scope, Service) -> 
      $scope.model = {} 
      $scope.model.value_one = 1 

      # Call the dependency 
      Service.getValue() 
      .success (data) -> 
       $scope.model.value_two = data 
      .error -> 
       $scope.model.value_two = 0 
     ] 
     ] 

這裏是依存服務:

angular.module("app.service") 
     .factory 'Service', ['$http', ($http) -> 

     getValue:() -> 
     options.method = "GET" 
     options.url = "example/fetch" 

     $http _.defaults(options) 

這裏是視圖:

<div> 
     {{model.value_one}} {{model.value_two}} 
    </div> 

我已經簡化了這一點,因爲我的目標只是瞭解如何連接它,我可以從那裏拿走它。我以這種方式構建它的原因是因爲我最初並沒有創建它。我正在爲現有項目編寫測試,並且我沒有任何其他方式配置它的能力。我試圖寫測試,但不能讓它做我想做的事。

我想測試以查看值是否綁定到視圖,並且如果可能的話還測試以查看控制器是否正確創建值。

這裏是我的本錢:

'use strict' 

    describe "the exampleDirective Directive", -> 

     beforeEach module("app.directive") 
     beforeEach module("app/partials/view.html") 

     ServiceMock = { 
     getValue :() -> 

     options.method = "GET" 
     options.url = "example/fetch" 

     $http _.defaults(options) 
     } 

    #use the mock instead of the service 
    beforeEach module ($provide) -> 
     $provide.value "Service", ServiceMock 
     return 

    $httpBackend = null 
    scope = null 
    elem = null 

    beforeEach inject ($compile, $rootScope, $injector) -> 

    # get httpBackend object 
    $httpBackend = $injector.get("$httpBackend") 
    $httpBackend.whenGET("example/fetch").respond(200, "it works") 

    #set up the scope 
    scope = $rootScope 

    #create and compile directive 
    elem = angular.element('<example-directive></example-directive>') 
    $compile(elem)(scope) 
    scope.$digest() 

我不知道我是多麼接近我,或者如果這是正確的,甚至。我想能夠斷言值正確地綁定到視圖。我使用Vojtajina的示例在我的karma.js文件中設置html2js以允許我抓取視圖。我已經做了大量的研究來找到答案,但我需要一些幫助。希望程序員比我能指出我正確的方向。謝謝。

回答

29

在業力中創建元素,然後使用帶指令名稱的.controller()函數來獲取控制器。對於你的榜樣,這些替代過去的幾行:

elem = angular.element('<div example-directive></div>'); 
$compile(elem)($rootScope); 
var controller = elem.controller('exampleDirective'); 

注意,那給了你如何定義你的指令,它應該是屬性,而不是作爲一個元素。我也不是100%肯定的,但我認爲你不需要scope.$digest;通常我只是把任何需要應用到scope.$apply(function() {})區塊。

+0

什麼是元素對象(第3行)?應該是elem到位?但仍然得到undefine –

+0

我相信中間行應該是:var element = $ compile(elem)($ rootScope); –

+0

我也認爲最後一行應該是var controller = elem.controller('exampleDirective'); –