2016-10-10 6 views
7

У меня возникли проблемы с доступом к контроллеру по директиве, которую я пытаюсь выполнить с помощью теста jasmine и karma testrunner. Директива выглядит следующим образом:Доступ к регулятору директивы 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

Вы можете получить доступ к нему, как это 'scope.ctrl' – Kliment

+0

мне легче контроллера это собственный файл, который вы могли бы, возможно, проверить легче без контекста директивы – Maccurt

+0

I попробовали 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

Хм, наверное, я где-то ошиблась. Я заработаю скрипку, когда у меня будет пятнадцать минут, и обновите свой ответ. – s3raph86

+0

Хорошо, я проверил и обновил свой ответ. Чтобы упростить, я удалил несколько зависимостей от контроллера, но вы должны просто добавить их обратно один за другим при разработке своих макетов и спецификаций. Вышеуказанное обязательно будет вводить учетную записьSearchCtrl как в спецификацию, так и в директиву, которая полностью заполняет ваше требование модульной проверки контроллера вашей директивы. – s3raph86

0

element.controller - дополнительный метод для AngularJS jqLite, поэтому, когда вы его регистрируете, вы видите метод jqLite .toString(). Вы должны позвонить ему и получить директивный контроллер. Element controller manual

4

Так близко!

element.controller является функцией и должно быть передано имя директивы, к которой вы пытаетесь получить контроллер. В этом случае было бы

ctrl = element.controller("accountSearch");
Смежные вопросы