如何测试 AngularJS 指令 [英] How to test AngularJS directives

查看:22
本文介绍了如何测试 AngularJS 指令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个将使用 AngularJS 的 Rails 3.2 应用程序.我可以让 Angular 做我需要做的事情,但是我很难弄清楚如何测试我正在做的事情.我正在使用guard-jasmine 使用PhantomJS 运行Jasmine 规范.

这是(相关的)html:

<div id="directive-element" class="directive-element">

</html>

javascript(在咖啡脚本中)看起来像:

window.Project =应用程序:angular.module('app', [])指令:{}Project.Directive.DirectiveElement =->限制:'C'链接:(范围、元素、属性)->element.html '你好世界'Project.App.directive 'directiveElement', Project.Directive.DirectiveElement

上面的代码完全符合它的意图.测试是问题所在.我根本无法让他们工作.这是我尝试过的一件事.发布此内容主要是为了在某处开始对话.

describe 'App.Directive.DirectiveElement', ->它更新指令元素",->注入($compile,$rootScope)->element = $compile('<div id="app" ng-app="app"><div id="directive'element" class="directive-element"></div></div>')期望(element.text()).toEqual('你好世界')

顺便说一句,我是 AngularJS 的新手,所以如果我没有遵循有关命名空间、模块等的任何最佳实践,我们将不胜感激.

如何进行测试以使其正常工作?

解决方案

这里是如何在 angular-ui/bootstrap 中测试警报指令.

这是另一组简单的测试, 用于按钮指令.

这里有一些提示:

  • 请务必告诉测试运行者您正在使用 beforeEach(module('myModule')) 测试哪个模块.

  • 如果您的指令中有外部 templateUrls,您将希望以某种方式为测试运行程序预先缓存它们.测试运行器不能异步GET 模板.在引导程序中,我们通过构建步骤将模板注入到 javascript 中,并使每个模板成为一个模块.我们使用 grunt-html2js grunt 任务.

  • 在您的测试中,使用 beforeEach 中的 inject 帮助程序来注入 $compile 和 $rootScope 以及您需要的任何其他服务.使用 var myScope = $rootScope.$new() 为每个测试创建一个新的范围.您可以执行 var myElement = $compile('<my-directive></my-directive>')(myScope); 来创建指令的实例,并可以访问其元素.

  • 如果一个指令创建了它自己的作用域并且您想对其进行测试,您可以通过执行 var directiveScope = myElement.children().scope() 来访问该指令的作用域- 它将获取元素的子元素(指令本身),并获取其作用域.

  • 对于测试超时,您可以使用 $timeout.flush() 结束所有挂起的超时.

  • 对于测试 Promise,请记住,当您解析 Promise 时,它​​会调用它的 then 回调,直到下一个摘要.所以在测试中你必须做很多事情: deferred.resolve();scope.$apply();.

您可以在引导程序存储库中找到针对不同复杂度的指令的测试.只需查看 src/{directiveName}/test/.

I am working on a Rails 3.2 app that will be using AngularJS. I can get Angular to do what I need, but I am having a very difficult time figuring out how to test what I'm doing. I am using guard-jasmine to run Jasmine specs using PhantomJS.

Here is the (relevant) html:

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

The javascript (in coffeescript) looks like:

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

The code above does exactly what it is intended to do. The tests are the problem. I can't get them to work at all. This is one thing I had tried. Posting this is mostly just to start the conversation somewhere.

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

As an aside, I am new to AngularJS, so if there are any best practices regarding namespacing, modules, etc. that I am not following, guidance would be appreciated.

How do I get a test for this to work?

解决方案

Here's how alert directive is tested in angular-ui/bootstrap.

Here's another simple set of tests, for the buttons directive.

Here are a few tips:

  • Be sure to tell the test runner what module you are testing with beforeEach(module('myModule')).

  • If you have external templateUrls in your directives, you'll want to somehow pre-cache them for the test runner. The test runner can't asynchronously GET templates. In bootstrap, we inject the templates into the javascript with a build step, and make each template a module. We use grunt-html2js grunt task.

  • In your tests, use the inject helper in a beforeEach to inject $compile and $rootScope and any other services you'll need. Use var myScope = $rootScope.$new() to create a fresh scope for each test. You can do var myElement = $compile('<my-directive></my-directive>')(myScope); to create an instance of your directive, and have access to its element.

  • If a directive creates its own scope and you want to test against it, you can get access to that directive's scope by doing var directiveScope = myElement.children().scope() - It will get the element's child (the directive itself), and get the scope for that.

  • For testing timeouts, you can use $timeout.flush() to end all pending timeouts.

  • For testing promises, remember that when you resolve a promise, it will not call its then callbacks until the next digest. So in tests you have to do this a lot: deferred.resolve(); scope.$apply();.

You can find tests for directives of varying complexity in the bootstrap repo. Just look in src/{directiveName}/test/.

这篇关于如何测试 AngularJS 指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆