web-dev-qa-db-fra.com

Comment tester les directives AngularJS

Je travaille sur une application Rails 3.2 qui utilisera AngularJS. Je peux obtenir Angular pour faire ce dont j'ai besoin, mais je traverse une période très difficile) comprendre comment tester ce que je fais. J'utilise guard-jasmine pour exécuter les spécifications Jasmine à l'aide de PhantomJS.

Voici le html (pertinent):

<html id="ng-app" ng-app="app">
  <div id="directive-element" class="directive-element">
  </div>
</html>

Le javascript (en coffeescript) ressemble à:

window.Project =
  App: angular.module('app', [])
  Directive: {}

Project.Directive.DirectiveElement =
  ->
    restrict: 'C'
    link: (scope, element, attrs) ->
      element.html 'hello world'
Project.App.directive 'directiveElement', Project.Directive.DirectiveElement

Le code ci-dessus fait exactement ce qu'il est censé faire. Les tests sont le problème. Je ne peux pas les faire travailler du tout. C'est une chose que j'avais essayée. Publier ceci est principalement juste pour commencer la conversation quelque part.

describe 'App.Directive.DirectiveElement', ->
  it 'updates directive-element', ->
    inject ($compile, $rootScope) ->
      element = $compile('<div id="app" ng-app="app"><div id="directive'element" class="directive-element"></div></div>')
      expect(element.text()).toEqual('hello world')

En passant, je suis nouveau sur AngularJS, donc s'il y a des meilleures pratiques concernant l'espace de noms, les modules, etc. que je ne suis pas en train de suivre, des conseils seraient appréciés.

Comment puis-je obtenir un test pour que cela fonctionne?

44
toadjamb

Voici comment la directive alert est testée dans angular-ui/bootstrap .

Voici un autre ensemble de tests simple, pour la directive boutons.

Voici quelques conseils:

  • Assurez-vous d'indiquer au lanceur de test le module que vous testez avec beforeEach(module('myModule')).

  • Si vous avez des templateUrl externes dans vos directives, vous voudrez en quelque sorte les pré-mettre en cache pour le lanceur de test. Le lanceur de test ne peut pas asynchrone GET modèles. Dans le bootstrap, nous injectons les modèles dans le javascript avec une étape de construction et faisons de chaque modèle un module. Nous utilisons la tâche de grognement grunt-html2js.

  • Dans vos tests, utilisez l'assistant inject dans un beforeEach pour injecter $ compile et $ rootScope et tout autre service dont vous aurez besoin. Utilisez var myScope = $rootScope.$new() pour créer une nouvelle portée pour chaque test. Vous pouvez faire var myElement = $compile('<my-directive></my-directive>')(myScope); pour créer une instance de votre directive, et avoir accès à son élément.

  • Si une directive crée sa propre portée et que vous souhaitez la tester, vous pouvez accéder à la portée de cette directive en faisant var directiveScope = myElement.children().scope() - Elle obtiendra l'enfant de l'élément (la directive elle-même) et la portée de cette.

  • Pour tester les délais d'expiration, vous pouvez utiliser $timeout.flush() pour mettre fin à tous les délais d'attente.

  • Pour tester les promesses, n'oubliez pas que lorsque vous résolvez une promesse, elle n'appellera pas ses rappels then jusqu'au prochain résumé. Donc, dans les tests, vous devez faire beaucoup de choses: deferred.resolve(); scope.$apply();.

Vous pouvez trouver des tests pour des directives de complexité variable dans le bootstrap repo . Regardez simplement dans src/{directiveName}/test/.

68
Andrew Joslin

Modèles de test angulaire peut vous aider, il existe des exemples à la fois dans coffeescript et javascript.

Voici un modèle de test pour vérifier que la directive d'exemple est rendant la sortie attendue .

12
daniellmb