1

I'm trying to test a directive. using controllerAs creates a toplevel scope where we can access its properties. however when debugging I try to access element.scope().property --I am getting undefined. Any help on why would be greatly appreciated.

--BugDirective

 (function() {
  'use strict';

  angular
    .module('debug-blog-app')
    .directive('avBug', avBug);

  function avBug() {
    return {
        restrict: 'E',
        templateUrl: 'views/directives/bug.html',
        scope: {
          bug: '='
        },
        controller: BugFormController,
        controllerAs: 'bugCtrl',
        bindToController: true
    };
  };

  BugFormController.$inject = ['$window', '$scope', 'BugService'];
  function BugFormController($window, $scope, BugService) {
    var vm = this;

    vm.updateBug = function(){
      BugService.updateBug(vm.bug);
    };

    vm.deleteBug = function(){
      if($window.confirm("Delete the Bug?!")){
        return BugService.deleteBug(vm.bug.id)
          .then(function(){
            $scope.$emit('bug.deleted', vm.bug);
          });
      }
    };
  };
})();

--Spec

'use strict'

describe('avBug Directive', function () {
    var bugCtrl,
        element,
        BugService,
        $scope,
        $rootScope;

    beforeEach(module('app'));

    beforeEach(inject(function($q, $compile, _$rootScope_, _BugService_) {
        $rootScope = _$rootScope_;


        var directiveMarkup = angular.element("<av-bug></av-Bug>");
        element = $compile(directiveMarkup)($rootScope);
        bugCtrl = element.scope().bugCtrl;


        BugService = _BugService_;


        spyOn(BugService, 'deleteBug').and.callFake(function() {
            var deferred = $q.defer();
            deferred.resolve('data');
            return deferred.promise;
        });

        spyOn($rootScope,'$emit').and.callThrough();
    }));

    it('should delete a bug', function() {
        bugCtrl.deleteBug(0);
        expect(BugService.deleteBug).toHaveBeenCalledWith(0);
        $rootScope.$digest();
        expect($rootScope.$emit).toHaveBeenCalledWith('bug.deleted');
    });
});

--index.html

<div class="container">
  <div ui-view></div>
</div>

--home.html

<av-bug bug="bug" ng-repeat="bug in homeCtrl.bugs"></av-bug>

2 Answers 2

1

I would also add, for unit testing purposes, that you can get the parent controllerAs with the same function that @Ramy Deeb post.

vm = element.scope().$$childTail.nameOfParentControllerAs

And for testing the element isolate scope, just get

isolateScope = element.isolateScope()

I hope this can help anyone like me ending here searching how to unit test directives and controllers calling them, all of them being using ControllerAs syntax.

Thanks you.

I would comment, but I cannot.

Sign up to request clarification or add additional context in comments.

Comments

0

Your controller is located at:

element.scope().$$childTail.bugCtrl

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.