使用$ parsers的jasmine单元测试角度指令

时间:2017-09-21 17:08:44

标签: javascript angularjs unit-testing jasmine

我遇到了一个问题,即找出一个指令的单元测试,该指令接受输入并用空字符串替换不是数字的任何东西。我收到错误undefined is not a constructor (evaluating 'input.val('1').trigger('input')')

问题在于触发器。 input.val返回一个空字符串。如果我不执行触发器,则不会调用$ parser函数代码。

在我的应用程序中进行测试时,它可以正常工作,只是无法了解如何测试它。

我知道它正在使用该指令,因为当我取出ng-model测试失败时number-only requires ngModel

我想要进行两项测试:

  • 输入一个数字,视图值是一个数字
  • 输入一个字母,视图值为空字符串。

这是我的指示

/**
 * @ngdoc object
 * @name components-helpers-number-only
 * @description
 *
 * Catch the value before it reaches the model in the parsers phase
 * replace any non digit (0-9) and replace with an empty string.  
 * This works for any input method.  Copy and paste / Dragon etc.
 *
 */
angular.module('components-helpers-number-only', [])
    /**
     * @ngdoc directive
     * @name components-helpers-number-only.directive:numberOnly
     * @restrict E
     * @replace true
     * @element ANY
     *
     * @description
     * Directive to display a standard number field,
     * along with binding and validation, link function initialises the controller passing references to all required resources
     *
     */
    .directive('numberOnly', function() {
        return {
            require: 'ngModel',
            link: function (scope, element, attr, ngModel) {
                // The parsers are before assigning a value to a model
                ngModel.$parsers.push(function (inputValue) {
                    // Replace anything apart from a value 0-9 with an empty string
                    var transformedInput = inputValue.toLowerCase().replace(/[^0-9]/g, '');

                    // If the values are the same no need to change the value.
                    if (transformedInput!=inputValue) {
                        ngModel.$setViewValue(transformedInput);
                        ngModel.$render();
                    }

                    return transformedInput;
                });
            }
        };
    });

这是我的单元测试

describe('Directive: numberOnlyDirective', function () {
    'use strict';

    var scope;
    var dummyElement1;
    var input;
    var ngModel;

    beforeEach(module('components-helpers-number-only'));

    beforeEach(inject(function ($compile, $rootScope) {
        scope = $rootScope.$new();

        dummyElement1 = angular.element(
            '<input type="text" ng-model="model" value="1" number-only />'
        );

        input = $compile(dummyElement1)(scope);

        ngModel = input.controller('ngModel');

    }))


    it('should define an input with number only directive', function () {
        expect(input).toBeDefined()



    });

    it('should set the value to 1 and set the view value to 1', function () {
        input.val('1').trigger('input');
        scope.$apply()
    });

})

1 个答案:

答案 0 :(得分:2)

我认为这是因为Angular的jqLit​​e没有.trigger(),它只支持.triggerHandler()。比较angular.element documentation page上实现的jQ方法。

仔细检查是否是这种情况的一种可能方法是在测试中暂时包含jQuery。如果AngularJS可用,它将使用完整的jQuery而不是jqLit​​e。如果您的测试在此时有效,则可能会出现问题,您可以看到.triggerHandler()是否仍能满足您的需求。