Comment l'Unité de Test Isolé Champ d'application de la Directive dans AngularJS
Ce qui est un bon moyen de l'unité de test isolé portée dans AngularJS
JSFiddle montrant l'unité de test
Directive extrait de
scope: {name: '=myGreet'},
link: function (scope, element, attrs) {
//show the initial state
greet(element, scope[attrs.myGreet]);
//listen for changes in the model
scope.$watch(attrs.myGreet, function (name) {
greet(element, name);
});
}
Je veux m'assurer que la directive est à l'écoute de modifications - ce qui ne pas travail isolé portée:
it('should watch for changes in the model', function () {
var elm;
//arrange
spyOn(scope, '$watch');
//act
elm = compile(validHTML)(scope);
//assert
expect(scope.$watch.callCount).toBe(1);
expect(scope.$watch).toHaveBeenCalledWith('name', jasmine.any(Function));
});
Mise à JOUR:
Je l'ai eu à travailler en vérifiant si la durée d'observateurs ont été ajoutés à l'enfant, mais il est très fragile et probablement en utilisant les accesseurs sans papiers moyen (aka sujets à changement sans préavis!).
//this is super brittle, is there a better way!?
elm = compile(validHTML)(scope);
expect(elm.scope().$$watchers[0].exp).toBe('name');
Mise à JOUR 2:
Comme je l'ai mentionné c'est fragile! L'idée fonctionne toujours, mais dans des versions plus récentes de AngularJS l'accesseur a changé à partir de scope()
à isolateScope()
:
//this is STILL super brittle, is there a better way!?
elm = compile(validHTML)(scope);
expect(elm.isolateScope().$$watchers[0].exp).toBe('name');
- Avez-vous trouver un moyen pour l'installation de l'espionnage?
- pas vraiment, comme avant il y a un moyen de le faire fonctionner mais c'est sujet à changement sans préavis afin de les utiliser à vos propres risques.
Vous devez vous connecter pour publier un commentaire.
Voir angulaire de l'élément de l'api docs. Si vous utilisez élément.portée() vous obtenez l'élément du champ d'application que vous avez définie dans le champ d'application de la propriété de votre directive. Si vous utilisez élément.isolateScope() vous obtenez l'ensemble isolé portée.
Par exemple, si votre directive ressemble à quelque chose comme ceci :
Puis l'appel de l'élément.portée() dans votre test sera de retour
Mais si vous appelez de l'élément.isolateScope (), vous obtiendrez
C'est vrai que du moment cinétique 1.2.2 ou 1.2.3, ne sais pas exactement.
Dans les versions précédentes vous aviez seul élément.champ d'application().
element.isolateScope()
retourneundefined
. Etelement.scope()
retourne un champ d'application qui ne contient pas tous les trucs que j'ai mis ma portée.element.children().isolateScope()
.scope()
et.isolateScope()
ne sont pas disponibles si debugInfoEnabled est faux. Cela signifie que vous manquez d'amélioration de la performance si vous souhaitez utiliser ces méthodes. Plus d'informations: docs.angularjs.org/guide/production#disabling-debug-dataVous pouvez faire
var isolateScope = myDirectiveElement.scope()
pour obtenir de l'isoler de la portée.Vous n'avez pas vraiment besoin de tester que $watch a appelé mais.. c'est plus de tests angularjs que les tests de votre application. Mais je suppose que c'est juste un exemple pour la question.
greet
la fonction et de l'espionner, et vérifier si cela est appelé - pas le $watch.isolateScope
variable à tous? Voir Ang commentaire sur cette tête d'oeuf vidéo (tête d'oeuf.io/cours/angularjs-tests unitaires-directive-champ d'application): à compter du Angulaire 1.2, pour récupérer les isolés portée, on doit utiliserelement.isolateScope()
au lieu deelement.scope()
code.angularjs.org/1.2.0/docs/api/angular.elementde déplacer la logique à un contrôleur séparé, c'est à dire:
et test-ci comme vous le feriez pour n'importe quel contrôleur de transmission de la portée de l'objet directement (voir Contrôleurs l'article ici pour un exemple).
si vous avez besoin de déclencher $regarder dans votre test à faire:
Je ne suis pas sûr que c'est possible avec les isoler de la portée (même si j'espère que quelqu'un prouve que j'ai tort). L'isolat de la portée qui sera créé dans la directive est, bien isolé, de sorte que le $regarder méthode dans la directive est différente de la portée de ce que vous êtes d'espionnage dans l'unité de test. Si vous modifiez la portée: {} à portée: true, le champ d'application de la directive héritera de fait et vos tests doivent passer.
Je suppose que ce n'est pas la meilleure solution, parce que parfois (beaucoup de temps), isoler le champ d'application est une bonne chose.