Access to the AngularJs control controller

I have several problems accessing my controller using the directive I'm trying to use unit test with jasmine and karma testrunner. The directive looks like this:

directive

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' } }]); 

This is the file of the test file, while I believe that everything is in order and correct (I hope):

test file file:

  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() }); 

I managed to print the directive controller (I think) on the console, which returns the following ambiguous message:

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

I cannot access any functions or properties of the directive, since they all return "undefined", what am I doing wrong?

+7
javascript angularjs unit-testing karma-runner jasmine
source share
3 answers

So close!

element.controller is a function and the name of the directive to which you are trying to get the controller should be passed. In this case, it will be

  ctrl = element.controller ("accountSearch"); 
+4
source share

Controllers for directives are actually completely injectable - instead of providing a constructor, you can simply call the controller by name. See Angular directive definition object document here: https://docs.angularjs.org/api/ng/service/ $ compile # directive-definition-object

In your case, when you want the unit test of the controller, you simply execute it as follows:

common.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(); }); }); 

Thus, you can simply enter your controller directly into your jasmine tests, just like any other controller you have.

Hope this helps.

+3
source share

element.controller is an optional method for AngularJS jqLite, so when you register it, you see the jqLite .toString() method. You must call him and get a directory controller. Element Controller Guide

0
source share

All Articles