2016-10-10 14 views
7

ジャスミンとカルマテストランナーで単体テストしようとしているディレクティブでコントローラにアクセスする際に、いくつか問題があります。ディレクティブは次のようになります。AngularJsディレクティブコントローラへのアクセス

テストケースファイル:

ディレクティブ

angular.module('Common.accountSearch',['ngRoute']) 

    .directive('accountSearch', [function() { 
     return { 
      controllerAs: 'ctrl', 
      controller: function ($scope, $element, $routeParams, $http) { 

       this.setAccount = function() { 
        var response = { AccountId : $scope.ctrl.searchedAccount.AccountId } 
        $scope.callback(response) 
       } 


       this.getAccounts = function(searchText){ 
        return $http.get('/api/CRMAccounts', { 
         params: { 
          retrievalLimit: 10, 
          search: searchText 
         } 
        }).then(function(response){ 
         return response.data; 
        }); 

       } 

      }, 
      scope : { 
       config : '=', 
       values : '=', 
       callback : '=' 
      }, 
      templateUrl : '/common/components/account-search/account-search.html', 
      restrict : 'EAC' 
     } 
    }]); 

ここでこれはこれまでのところ、私はすべてのため、正しい(私は願っています)であると信じてテストケースファイルです

describe("Account search directive logic tests", function(){ 
    var element,$scope,scope,controller,template 

    beforeEach(module("Common.accountSearch")) 


    beforeEach(inject(function (_$compile_, _$rootScope_,_$controller_,$templateCache) { 
    template = $templateCache.get("components/account-search/account-search.html") 
    $compile = _$compile_; 
    $rootScope = _$rootScope_; 
    $controller = _$controller_; 
    scope = $rootScope.$new(); 
    element = $compile(template)(scope) 
    ctrl = element.controller 
    scope.$digest(); 
    // httpBackend = _$httpBackend_; 
    })); 




    it(" sets the account and calls back.", inject(function() { 

    console.log(ctrl) 
    expect(ctrl).toBeDefined() 
    })); 
    //httpBackend.flush() 
}); 

私は、次のあいまいなメッセージを返すコンソールに指示文のコントローラーを印刷することができました。

LOG: function (arg1, arg2) { ... } 

ディレクティブのすべての機能やプロパティにアクセスすることができません。すべてが「未定義」を返していますが、何が間違っていますか?

+0

だろうあなたは、私はあなたがおそらくディレクティブ – Kliment

+0

のようにアクセスすることができますscope.ctrlを試してみました、それは私がやった拳のものの1つでした。それはうまくいきませんでした。 – Maccurt

+0

のコンテキストなしで簡単にテストすることができること、それはコントローラの簡単には、それが自分のファイルで見つけるこの 'scope.ctrl' – nagrom97

答えて

3

指令のコントローラは、実際には完全に注入可能です。コンストラクタを提供する代わりに、コントローラを名前で参照するだけで済みます。ここでの角度のためのディレクティブ定義オブジェクトのドキュメントを参照してください。

共通:あなたはユニットテストにあなたはこのようにそれを行うだろうと、コントローラを配置したい場所をhttps://docs.angularjs.org/api/ng/service/ $あなたのケースでは#指令精細・オブジェクト

をコンパイルします。 accountSearch.js

angular.module('Common.accountSearch', []) 
    .directive('accountSearch', [function() { 
     return { 
      controller: 'accountSearchCtrl', 
      scope: { 
       config : '=', 
       values : '=', 
       callback : '=' 
      }, 
      templateUrl : '/common/components/account-search/account-search.html', 
      restrict: 'EAC' 
     } 
    }]) 
    .controller('accountSearchCtrl', ['$scope', function ($scope) { 
     $scope.setAccount = function() { 
      var response = { 
       AccountId: $scope.ctrl.searchedAccount.AccountId 
      }; 
      $scope.callback(response); 
     } 

     $scope.getAccounts = function (searchText) { 
      // Code goes here... 
     } 
    }]); 

common.accountSearch-spec.js

describe("Account search directive logic tests", function() {  
    var controller, scope; 

    beforeEach(module("Common.accountSearch")); 

    beforeEach(inject(function (_$controller_, _$rootScope_) {   
     $rootScope = _$rootScope_; 
     scope = $rootScope.$new(); 
     controller = _$controller_('accountSearchCtrl', { '$scope': scope });   
    })); 

    it(" sets the account and calls back.", function() { 
     expect(controller).toBeDefined(); 
    }); 
}); 

このようにすれば、他のコントローラーのようなジャスミンテストにコントローラを直接注入することができます。

これが役に立ちます。

+0

Iveはこれを試してみるとうまくいきません。あなたは例を追加できますか? – dopatraman

+0

うーん、私はどこかで間違いを犯したと思う。私は15分持っているときに働くフィドルを一緒に投げ、私の答えを更新します。 – s3raph86

+0

申し訳ありませんが、私はテストし、私の答えを更新しました。簡単にするために、私はコントローラーからいくつかの依存関係を削除しましたが、モックと仕様を開発するときに、それらを1つずつ追加するだけで済みます。上記はaccountSearchCtrlを仕様書と指令に注入します。これにより、指令のコントローラの単体テスト要件が満たされます。 – s3raph86

0

element.controllerは、AngularJS jqLit​​eの追加メソッドです。ログに記録するときは、jqLit​​eメソッド.toString()が表示されます。それを呼び出して指令コントローラを取得する必要があります。 Element controller manual

4

だからこそ!

element.controllerは関数であり、コントローラを取得しようとするディレクティブの名前を渡す必要があります。この場合、それは

ctrl = element.controller("accountSearch");
関連する問題