45

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

这是(相关的)html:

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

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

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

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

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

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

我如何得到这个工作的测试?

4

2 回答 2

69

以下是在 angular-ui/bootstrap 中测试 alert 指令的方式

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

这里有一些提示:

  • 一定要告诉测试运行者你正在测试什么模块beforeEach(module('myModule'))

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

  • 在您的测试中,使用 a 中的inject帮助beforeEach器来注入 $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();.

您可以在bootstrap repo中找到针对不同复杂度的指令的测试。进去看看src/{directiveName}/test/

于 2012-10-06T14:21:17.287 回答
12

Angular Test Patterns可能会对您有所帮助,coffeescript 和 javascript 中都有示例。

这是一个测试模式,用于验证示例指令是否呈现预期的输出

于 2013-09-17T21:34:33.403 回答