How to Test an Angular Directive's Linking Function Using It's Isolate Scope

image-post Have you ever wanted to get the scope of a linking function in a directive for testing. Let me rephrase that. Have you ever wanted to test the isolate scope within your directive's linking function? You probably have if your are a fan of well written and maintainable code. So I was trying to test my brand spanking new directive lets call it "myPerogative". Now myPerogative just happens to have an isolate scope like most directives. Normally when I test I use this sort of syntax:

NOTE: I write my Angular tests with Jasmine. So any tests you see will use Jasmine's matchers and setup. This Plunker will be used to demonstrate this blog post

     beforeEach(inject(function ($rootScope, $controller) {

        $scope = $rootScope.$new();


        controller = $controller('MyController', {
            '$scope': $scope
        });

However, this works will only controllers that are registered with the $controller service.

Your probably thinking:

"Britz we can have controllers in our directives instead of linking functions"

Yes that is true, however, according to the Angular Docs. (All the way on the bottom of the page)

bestpractice

You can see that controllers within directive really should only be used to create a sort of API within other 'dependant' directives that have the require option. Anyways, I digress.

In order to test this linking function we need to get a handle on the actual isolated scope of the directive. To do this is simple , but not well documented. There is a great video by John Lindquist at EggheadIO found here: testing directive scope that helped me out a lot.

Here is the Plunker with the directive and tests to do linking function testing.

The main thing to get out of this are the process of steps here which are:

  1. use the $compile service to force your directive to mutate itself to your template
  2. call a $scope.$digest to 'refresh' your scopes/models
  3. test isolate scope with the element variable obtained with $compile service.
    a. ie - element = $compile('<div my-perogative></div>')($scope);
    b. test like so: element.scope().<whatever scope var u like>
  4. Dont forget to $scope.digest() on major model changes

Hope this helps