Carl
Carl

Reputation: 861

AngularJS Unit Test Directive with Input

I am using Angular v1.6 with Jasmine and I'm trying to unit test a working directive in our angular application by entering an input value but I cannot get the directive to fire properly.

Directive

.directive('percentage', function() {
        return {
            restrict: 'A',
            require: 'ngModel',
            link: function(scope, element, attr, ngModel) {

                function fromUser(value) {
                    return value / 100;
                }

                function toUser(value) {
                    return Math.round(value * 100);
                }
                ngModel.$parsers.push(fromUser);
                ngModel.$formatters.push(toUser);
            }
        };
    })

Unit Test

describe('percentageDirective', function() {
  beforeEach(module('app'));

      // Inject $rootScope and $compile
      var scope, element;
      beforeEach(inject(function($rootScope, $compile) {
        // Set up the scope with test data
        scope = $rootScope.$new();

        scope.value = 0;

        // Create an element
        element = angular.element('<input type="number" percentage ng-model="value"></input>');

        // Compile that element with your scope
        element = $compile(element)(scope);

        // Run the digest cycle to compile the element
        $rootScope.$digest();

        // Find the input control: 
        var dirElementInput = element.find('input');

        // Set some text
        angular.element(dirElementInput).val('25').triggerHandler('input');

        scope.$apply();
      }));

      it("should display the decimal value", function() {
        expect(scope.value).toEqual('0.25');
      });
});

The scope value never changes and remains at 0. Can someone help on how to trigger the input change?

Upvotes: 0

Views: 1122

Answers (1)

felixmosh
felixmosh

Reputation: 35473

Looks like you have an issue with element.find('input'), find searches at the children of the given element, it won't return as a result the element itself. Therefore, all your operations are made on an empty angular element wrapper.

If you will try to console.log(dirElementInput.length) you will see that this wrapper is empty.

You can change that to var dirElementInput = element[0]; and the test will pass.

Working example: https://embed.plnkr.co/DVUoMAUcDXcMl6tp521D/

Upvotes: 3

Related Questions