在视角形式指令的单元测试中将视图值设置为输入字段

时间:2014-10-15 00:48:55

标签: angularjs unit-testing angular-directive

我有一个构建表单的指令:

app.directive('config', function() {
  return {
    restrict: 'E',
    scope: {
      data: '='
    },
    template: '<form name="configForm">' +
      '<input type="number" max="10" ng-model="config.item" name="configItem"/>' +
      '<div class="form-error" ng-show="configForm.$error.max">Error</div>' + 
      '</form>',
    controller: 'ConfigDirectiveController',
  };
});

我想要做的是通过单元测试验证在给定输入的情况下将显示错误消息。使用角度1.2我可以修改$ scope.config.item,它会更新视图值并显示错误。

尽可能接近,使用angular 1.3,如果模型未通过验证,则视图值不会更新...所以我需要修改视图值以确保显示错误消息。

如何访问“configItem”输入以便我可以设置视图值以确保显示错误消息?

编辑以显示单元测试

我看到该值设置正确,但错误仍然有一个应用于标记的ng-hide。当我查看页面并手动更改输入值时,将删除ng-hide,如果我输入大于10的内容,则会显示错误。

  beforeEach(inject(function($compile, $rootScope) {
      element = angular.element('<config data="myData"></config>');
      $scope = $rootScope.$new();
      $scope.myData = {};
      element = $compile(element)($scope);
    }));

    it('should warn that we have a large number', function() {
      var input = element.find('[name="configItem"]')[0];
      $scope.$apply(function() {
        angular.element(input).val('9000000001');
      });
      errors = element.find('[class="form-error ng-binding"]');
      expect(errors.length).toBe(1);
    })

2 个答案:

答案 0 :(得分:62)

以下是我对基于输入的指令进行单元测试的方法(为清晰起见,省略了很多代码!)您要了解的重要内容是:

angular.element(dirElementInput).val('Some text').trigger('input');

这是完整的单元测试:

  it('Should show a red cross when invalid', function () {

    dirElement = angular.element('<ng-form name="dummyForm"><my-text-entry ng-model="name"></my-text-entry></ng-form>');

    compile(dirElement)(scope);
    scope.$digest();

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

    // Set some text!
    angular.element(dirElementInput).val('Some text').trigger('input');
    scope.$apply();

    // Check the outcome is what you expect! (in my case, that a specific class has been applied)
    expect(dirElementInput.hasClass('ng-valid')).toEqual(true);
  });

答案 1 :(得分:31)

如果您使用Angular和jQuery,前面的答案是正确的,但对于没有jQuery的Angular(使用jqlite),您可以使用triggerHandler代替here获取完整的API)

it('foos to the bar', function() {
  el.val('Foo').triggerHandler('input');

  // Assuming el is bound to scope.something using ng-model ...
  expect(scope.something).toBe('Foo');
});