How to change a constant value in a Karma test

I have an Angular directive that sets the value of some property $scope

based on the value of an injected constant. I want to check that this value is correctly initialized from a constant, so I would like to change the constant value in a separate block it

. (Preferably within one, but changing the value between multiple blocks will also be OK)

Is this possible and how can I do it?

simplified example:

//////// directive ////////
angular.module('myApp.directives', [])
.constant('THE_CONSTANT', 'hello world')
.directive('myDirective', ['THE_CONSTANT', function (THE_CONSTANT) {

    return {
        restrict: 'E',
        link: function ($scope) {
            $scope.propertyBasedOnConstant = THE_CONSTANT;
        }
    };
}]);

//////// test ////////
describe('myDirective', function () {
    var $element, $scope;

    beforeEach(module('myApp.directives'));

    beforeEach(module(function ($provide) {
        $provide.constant('THE_CONSTANT', 'foo');
    }));

    beforeEach(inject(function ($rootScope, $compile) {
        $scope = $rootScope;
        $element = angular.element('<my-directive></my-directive>');
        $compile($element)($scope);
        $scope.$digest();
    }));

    afterEach(function () {
        $scope.$destroy();
        $element.remove();
    });

    it("should correctly reflect the constant value", function() {
        expect( $scope.propertyBasedOnConstant ).to.equal('foo');

        // now I want to change the constant value and re-initialize the directive
    });    
});

      

+3


source to share


2 answers


You provide constant

the module undefined

.

Change the beforeEach block to something like this and it should just work ™:

var $scope, $element, MOCKED_CONSTANT;

beforeEach(function () {
  MOCKED_CONSTANT = 'foo';

  module('myApp.directives', function ($provide) {
    $provide.constant('THE_CONSTANT', MOCKED_CONSTANT);
  });

  inject(function ($rootScope, $compile) {
    $scope       = $rootScope.$new(); // Don't forget to call .$new()!
    var template = angular.element('<my-directive></my-directive');
    $element     = $compile(template)($scope); // Store the reference to the compiled element, not the raw string.
    $scope.$digest();
  });
});

it("should correctly reflect the constant value", function() {
  expect( $scope.propertyBasedOnConstant ).to.equal(MOCKED_CONSTANT);
  // expect( $scope.propertyBasedOnConstant ).to.equal('foo');
});

      




If you need to change the constant value between it

's, I would extract the call module

to a helper function as well inject

. For example:

function setupModule (constant) {
  module('myApp.directives', function ($provide) {
    $provide.constant('THE_CONSTANT', constant);
  });
}

function injectItAll () {
  inject(function ($rootScope, $compile) {
    $scope       = $rootScope.$new(); // Don't forget to call .$new()!
    var template = angular.element('<my-directive></my-directive');
    $element     = $compile(template)($scope); // Store the reference to the compiled element, not the raw string.
    $scope.$digest();
  });
}

      

And then in your spec, you would do:

it('equals banana', function () {
  setupModule('banana');
  injectItAll();
  expect($scope.propertyBasedOnConstant).to.equal('banana');
});

      

+4


source


By definition, a constant is an identifier with an associated value that cannot be changed. Instead of changing the constant value, why not insert the constant and use it in your expectations.



describe('myDirective', function () {
    var $element, $scope,
      THE_CONSTANT;

    beforeEach(module('myApp.directives'));

    beforeEach(module(function (_THE_CONSTANT_) {
      THE_CONSTANT = _THE_CONSTANT_;
    }));

    beforeEach(inject(function ($rootScope, $compile) {
        $scope = $rootScope;
        $element = angular.element('<my-directive></my-directive>');
        $compile($element)($scope);
        $scope.$digest();
    }));

    afterEach(function () {
        $scope.$destroy();
        $element.remove();
    });

    it("should correctly reflect the constant value", function() {
        expect( $scope.propertyBasedOnConstant ).to.equal(THE_CONSTANT);
    });    
});

      

+1


source







All Articles