2013-03-01 4 views
12

Je suis en train d'implémenter une directive simple qui représente un champ de formulaire avec tous ses extras comme label, field error, regex le tout sur une seule ligne.

La directive est la suivante:

<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> 

Maintenant, je veux tester la liaison de données entre le champ d'application de la directive et la portée des parents.

Le test est:

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'); 
    }); 

Ce problème est que je ne sais pas pourquoi test ne passe pas, même la directive fonctionne correctement. Here is a fiddle of the directive.

Et voici le test complet et le test mis en place.

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'); 
}); 

Comme vous pouvez le voir, je veux affirmer que l'entrée de la forme se reflète dans la portée variable définie dans l'attribut « modèle » fourni par la portée des parents.

Ai-je oublié quelque chose ici? Merci de votre aide ...!

Répondre

28

Il vous manque l'appel scope.$apply() après avoir défini la valeur d'entrée, afin que la modification ne soit jamais digérée. Dans le cycle de vie normal de l'application, cela se produit automatiquement, mais vous devez le déclencher manuellement dans vos tests.

Jetez un coup d'œil à https://github.com/angular/angular.js/blob/master/test/ng/directive/formSpec.js pour de nombreux exemples.

+0

Il existe une sérieuse différence entre ce que vous devez savoir pour écrire une application angulaire simple et pour tester une application angulaire simple. Merci pour cela! –

7

Utilisez $ scope. $ Digest() après avoir ajouté une condition pour exécuter la surveillance. Il fera feu.

Questions connexes