2013-03-01 5 views
12

Я реализую простую директиву, которая представляет поле формы со всеми его дополнениями, такими как метка, поле ошибки, регулярное выражение, все в одной строке.

Директива выглядит следующим образом:

<div ng-controller="parentController"> 

     {{username}} 
<!-- the directive -- > 
     <form-field label="Username:" regex="someRegex" constrainsViolationMessage="someValidationMessage" model="username" place-holder="some input value"> 
     </form-field> 
    </div> 

Теперь я хочу, чтобы проверить привязку данных между масштабом директивы и родительской области.

Тест:

it("should bind input field to the scope variable provided by parent scope ! ", function() { 
     var formInput = ele.find('.form-input'); 
     formInput.val("some input"); 
     expect(ele.find('p').text()).toEqual('some input'); 
    }); 

Эта проблема в том, что я не знаю, почему тест не проходят, даже директива работает правильно. Here is a fiddle of the directive.

И вот весь тестовый тест.

var formsModule = angular.module('forms', []); 

formsModule.controller('parentController', function ($scope) { 
}); 


formsModule.directive('formField', function() { 

    var label; 
    var constrainsViolationMessage; 
    var placeHolder; 
    var model; 


    return { 
     restrict:'E', 
     transclude:true, 
     replace:false, 
     scope:{ 
      model:'=' 
     }, 
     link:function (scope, element, attr) { 

      console.log("link function is executed .... "); 

      scope.$watch('formInput', function (newValue, oldValue) { 
       console.log("watch function is executed .... !") 
       scope.model = newValue; 
      }); 
      scope.label = attr.label; 
     }, 
     template:'<div class="control-group ">' + 

      '<div class="form-label control-label">{{label}}</div> ' + 

      '<div class="controls controls-row"> ' + 

      '<input type="text" size="15" class="form-input input-medium" ng-model="formInput" placeholder="{{placeHolder}}">' + 

      '<label class="error" ng-show={{hasViolationConstrain}}>{{constrainsViolationMessage}}</label>' + 

      '</div>' 
    } 
}); 


beforeEach(module('forms')); 

var ele; 

var linkingFunction; 

var elementBody; 


var scope; 
var text = ""; 
var placeHolder = "filed place holder"; 
var label = "someLabel"; 
var regex = "^[a-z]{5}$"; 


beforeEach(inject(function ($compile, $rootScope) { 

     scope = $rootScope; 


     elementBody = angular.element('<div ng-controller="parentController">' + 
      '<p>{{username}}</p>' + 
      '<form-field label="Username:" regex="someRegex" constrainsViolationMessage="someValidationMessage" model="username" place-holder="some input value"> </form-field>'); 

     ele = $compile(elementBody)(scope); 
     scope.$digest(); 
    } 
)); 


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


iit("should bind input field to the scope variable provided by parent scope ! ", function() { 
    var formInput = ele.find('.form-input'); 
    formInput.val("some input"); 
    expect(ele.find('p').text()).toEqual('some input'); 
}); 

Как вы можете видеть, я хочу утверждать, что форма ввода отражается в области видимости переменной набора в атрибуте «модели», предоставленной родительской области.

Я что-то упустил? Спасибо, что помогли мне ...!

ответ

28

Вам не нужен звонок scope.$apply() после установки входного значения, поэтому изменение никогда не переваривается. В обычном жизненном цикле приложения это произойдет автоматически, но вы должны вручную активировать это в своих тестах.

Посмотрите на https://github.com/angular/angular.js/blob/master/test/ng/directive/formSpec.js за тонну примеров.

+0

Существует серьезное несоответствие между тем, что вам нужно знать, чтобы написать простое угловое приложение и протестировать простое угловое приложение. Спасибо за это! –

7

Использовать $ scope. $ Digest() после добавления условия для выполнения watch. Он будет стрелять в часы.

Смежные вопросы