Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Karma/Jasmine testing custom directive controller

I'm trying to test an AngularJS custom directive with Karma + Jasmine. I found a way to do it checking many references around the web. But the solution doesn't appear to be the correct way. Let's first check an example, this is the test.js:

angular.module("app", [])
  .directive("test", function() {
    return {
      restrict: 'E',
      scope: {
        defined: '='
      },
      templateFile: "test.html",
      controller: function($scope) {
        $scope.isDefined = function() {
          return $scope.defined;
        };
      }
    };
  });

describe("Test directive", function() {
  var elm, scope;

  beforeEach(module("app"));
  beforeEach(module("test.html"));

  beforeEach(inject(function($rootScope, $compile, $injector) {
    elm = angular.element("<test defined='defined'></test>");

    scope = $rootScope;
    scope.defined = false;

    $compile(elm)(scope);
    scope.$digest();
  }));

  it("should not be initially defined", function() {
    expect(elm.scope().$$childTail.isDefined()).toBe(false);
  });
});

Now the directive template file test.html:

<button data-ng-click='defined = true'></button>

And finally the karma.conf.js:

module.exports = function(config) {
  config.set({
    basePath: '',
    frameworks: ['jasmine'],

    files: [
      'angular.min.js',
      'angular-mocks.js',
      'test.js',
      'test.html'
    ],

    exclude: [],

    preprocessors: {
      "test.html": ['ng-html2js']
    },

    reporters: ['progress'],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    browsers: ['Firefox'],
    singleRun: true
  });
};

I was running the tests with the following command line:

karma start karma.conf.js

What appears to be really strange to me is that the scope function defined in the controller can only be accessed by the $$childTail attribute. If I try to call it directly from the element's scope I got an undefined value elm.scope().isDefined(). Does someone has a better solution for this?

Thanks!

like image 834
faersons Avatar asked Mar 24 '14 13:03

faersons


1 Answers

Because your directive uses an isolated scope, instead of

elm.scope()

you should be able to use

elm.isolateScope()

The function isolateScope is explained (briefly) at http://docs.angularjs.org/api/ng/function/angular.element

like image 116
Michal Charemza Avatar answered Nov 15 '22 01:11

Michal Charemza