title: Testing Angular Directive with Dependencies like $location and $routeParams
body: <p>Thie question is somewhat related to <a href="https://stackoverflow.com/questions/20694690/how-do-i-inject-a-mock-dependency-into-an-angular-directive-with-jasmine-on-karm">How do I inject a mock dependency into an angular directive with Jasmine on Karma</a>. But I cant figure it out. Heres the thing:</p>
  
  <p>I have a simple angular directive for rendering a head-part of my apllication with several parameters. One is passed, two came from the URL vie $location and $routeParam. The directive looks like this:</p>
  
  <pre><code>    'use strict';
  myApp.directive('appHeader', ['$routeParams', '$location', function ($routeParams, $location) {
      return {
          restrict: 'E',
          templateUrl: 'path/to/partials/template.html',
          scope: {
              icon: '@icon'
          },
          link: function (scope, element, attributes) {
              var lastUrlPart = $location.path().split('/').pop();
              scope.project = $routeParams.itemName;
              scope.context = lastUrlPart === scope.project ? '' : lastUrlPart;
          }
      };
  }]);
  </code></pre>
  
  <p>This is called via <code>&lt;app-header icon="bullhorn"&gt;&lt;/app-header&gt;</code>.</p>
  
  <p>Now I want to add some tests. As for the template rendering I'm done. The following works like expected. The test passes.</p>
  
  <pre><code>describe('appHeader', function () {
      var element, scope;
  
      beforeEach(module('myApp'));
      beforeEach(module('myAppPartials'));
  
      beforeEach(inject(function ($rootScope, $compile) {
          element = angular.element('&lt;app-header icon="foo"&gt;&lt;/app-header&gt;');
          scope = $rootScope;
          $compile(element)(scope);
          scope.$digest();
      }));
  
      it('should contain the glyphicon passed to the directive', function () {
          expect(element.find('h1').find('.glyphicon').hasClass('glyphicon-foo')).toBeTruthy();
      });
  
  });
  </code></pre>
  
  <p>Now I want to test that scope.context and scope.project are set accordingly to the dependencies $location and $routeParams, which I want to mock of course. How can I acieve this.</p>
  
  <p>I tried for instance the answer from the question linked above:</p>
  
  <pre><code>beforeEach(module(function ($provide) {
          $provide.provider('$routeParams', function () {
              this.$get = function () {
                  return {
                      itemName: 'foo'
                  };
              };
          });
      }));
  </code></pre>
  
  <p>But In my test </p>
  
  <pre><code>it('should set scope.project to itemName from $routeParams', function () {
          expect(scope.project).toEqual('foo');
  });
  </code></pre>
  
  <p><code>scope.project</code> is undefined:</p>
  
  <pre><code>Running "karma:unit:run" (karma) task
  Chrome 35.0.1916 (Mac OS X 10.9.3) appHeader should set scope.project to itemName from routeParams FAILED
          Expected undefined to equal 'foo'.
          Error: Expected undefined to equal 'foo'.
  </code></pre>
  
  <p>As for the location dependency I tried to setUp a Mock mysel like this:</p>
  
  <pre><code>var LocationMock = function (initialPath) {
              var pathStr = initialPath || '/project/bar';
              this.path = function (pathArg) {
                  return pathArg ? pathStr = pathArg : pathStr;
              };
          };
  </code></pre>
  
  <p>Then injection $location in the before each and set a spyOn to the calling of path() like this:</p>
  
  <pre><code>spyOn(location, 'path').andCallFake(new LocationMock().path);
  </code></pre>
  
  <p>But then, scope.context is undefined, too. </p>
  
  <pre><code>it('should set scope.context to last part of URL', function () {
      expect(scope.context).toEqual('bar');
  });
  </code></pre>
  
  <p>Can someone please point out what I am doing wrong here?</p>