unit-testing - 测试自定义验证 angularjs 指令

标签 unit-testing angularjs angularjs-directive

此自定义验证指令是官方 Angular 站点上提供的示例。 http://docs.angularjs.org/guide/forms 它检查文本输入是否采用数字格式。

var INTEGER_REGEXP = /^\-?\d*$/;
app.directive('integer', function() {
  return {
    require: 'ngModel',
    link: function(scope, elm, attrs, ctrl) {
      ctrl.$parsers.unshift(function(viewValue) {
        if (INTEGER_REGEXP.test(viewValue)) {
          // it is valid
          ctrl.$setValidity('integer', true);
          return viewValue;
        } else {
          // it is invalid, return undefined (no model update)
          ctrl.$setValidity('integer', false);
          return undefined;
        }
      });
    }
  };
});

为了对该代码进行单元测试,我编写了以下内容:

describe('directives', function() {
  beforeEach(module('exampleDirective'));

  describe('integer', function() {
    it('should validate an integer', function() {
      inject(function($compile, $rootScope) {
        var element = angular.element(
          '<form name="form">' +
            '<input ng-model="someNum" name="someNum" integer>' +
          '</form>'
          );
        $compile(element)($rootScope);
        $rootScope.$digest();
        element.find('input').val(5);
        expect($rootScope.someNum).toEqual(5);
      });
    });
  });
});

然后我收到此错误:

Expected undefined to equal 5.
Error: Expected undefined to equal 5.

我在各处都放置了 print 语句来查看发生了什么,看起来该指令从未被调用过。 测试这样的简单指令的正确方法是什么?

最佳答案

其他答案的测试应写为:

describe('directives', function() {
  var $scope, form;
  beforeEach(module('exampleDirective'));
  beforeEach(inject(function($compile, $rootScope) {
    $scope = $rootScope;
    var element = angular.element(
      '<form name="form">' +
      '<input ng-model="model.somenum" name="somenum" integer />' +
      '</form>'
    );
    $scope.model = { somenum: null }
    $compile(element)($scope);
    form = $scope.form;
  }));

  describe('integer', function() {
    it('should pass with integer', function() {
      form.somenum.$setViewValue('3');
      $scope.$digest();
      expect($scope.model.somenum).toEqual('3');
      expect(form.somenum.$valid).toBe(true);
    });
    it('should not pass with string', function() {
      form.somenum.$setViewValue('a');
      $scope.$digest();
      expect($scope.model.somenum).toBeUndefined();
      expect(form.somenum.$valid).toBe(false);
    });
  });
});

请注意,$scope.$digest() 现在是在 $setViewValue 之后调用的。这会将表单设置为“脏”状态,否则它将保持“原始”状态,这可能不是您想要的。

关于unit-testing - 测试自定义验证 angularjs 指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15219717/

相关文章:

javascript - 如何在angularjs中保持选中的下拉项

javascript - AngularJS:使用 $state.go() 将对象传递到状态

javascript - 单击函数之间的 Angular ,共享指令模板

c# - 如何使用不同的模型设置使单元测试运行两次

javascript - AngularJS - 如何停止重新渲染模板?

javascript - 根据输入验证启用/禁用按钮

AngularJS:限制自定义 contenteditable 指令中的用户输入

c# - 如何将对象包装在动态对象中?

java - 如何在测试中以不同的方式模拟具有相同参数的静态方法?

unit-testing - 使用 Behat 2.0,我应该把步骤放在哪里?