Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS - Testing a directive's link function, how to spy on controller

If I have directive like this

JS:

app.controller('MyController', function($scope) {
  this.someMethod = function() {
  };
});

app.directive('myDirective', function() {
  return {
    scope: true
    link: function(scope, elem, attrs, controller) {
      controller.someMethod();
    }
    controller: 'MyController',
  }
});

I want to create a Jasmine spy to ensure that the link function called controller.someMethod, but this will not work:

Spec:

var elem = angular.element('<div my-directive></div>');
var scope = $rootScope.new();
$compile(elem)(scope);

var ctrl = elem.controller('myDirective');
spyOn(ctrl, 'someFunc').andCallThrough();

The spy is created too late, because the controller was instantiated and the link function called in the $compile statement.

What other ways are there for spying on something that happens in the link function? Is it possible to maybe instantiate the controller before hand and pass it into $compile?

like image 405
hgcrpd Avatar asked Sep 12 '13 07:09

hgcrpd


1 Answers

From the AngularJS Developer Guide's page on Directives:

Best Practice: use controller when you want to expose an API to other directives. Otherwise use link.

I would suggest creating a service for whatever someMethod() does. Then you can mock and spy on that service. Otherwise you may have to look for some other sign that what you wanted to happen has actually happened.

like image 120
Austin Thompson Avatar answered Oct 24 '22 12:10

Austin Thompson