ngAnimate 1.4.7单元测试不调用动画功能

时间:2015-10-29 03:53:18

标签: angularjs unit-testing coffeescript ng-animate

我一直在this tutorial工作,并且谷歌搜索广告,但我似乎无法获得似乎正在运行的小型ngAnimate单元测试。

ngAnimate在应用中运作良好。所有Angular核心库都是1.4.7版本。

模块

angular.module 'MyAnimation', [ 'ngAnimate' ]
  .animation '.added-class', ->
    addClass: (element, className, done) ->
      console.log 'add class triggered'
      element.css 'opacity', '0.5'
      done()

测试

describe 'MyAnimation', ->
  beforeEach -> module 'ngAnimate'
  beforeEach -> module 'ngAnimateMock'
  beforeEach -> module 'MyAnimation'

  it 'animates', -> inject ($animate, $rootScope, $rootElement) ->
    $animate.enabled(true)
    divElement = angular.element '<div>my div</div>'

    # Kick off initial digest loop in which no animations are run.
    $rootScope.$digest()

    # Trigger animation.
    $animate.addClass divElement, 'added-class'
    $rootScope.$digest()

    # Tried this, doesn't seem to do anything.
    # $animate.flush()

    # Results in AssertionError: expected '' to equal '0.5'
    expect(divElement.css('opacity')).to.eq '0.5'

我确定该模块已包含在测试中,但触发$animate.enter甚至无法获得log输出。

我已尝试使用其他$animate功能,但无处可去。帮助

1 个答案:

答案 0 :(得分:9)

在对Angular的源代码进行了一些认真的挖掘之后,罪魁祸首似乎是内部检查areAnimationsAllowed,Angular使用它来确定是否提前中止动画。除此之外,检查被动画的节点是$rootElement和文档正文的后代。

这里有两个选择。

  1. Plunker将您动画的节点附加到$rootElement并将$rootElement附加到正文。后者是必要的,因为ngMock实际上存在$rootElement并且在内存中保留了分离的<div>节点。 实施例
  2. var element, body, root;
    beforeEach(module('ngAnimate', 'ngAnimateMock', 'MyAnimation'));
    beforeEach(inject(function ($animate, $document, $rootElement, $rootScope) {
      // enable animations globally
      $animate.enabled(true);
    
      // create a node to be animated and inject it into the DOM
      element = angular.element('<div></div>');
      root = $rootElement.append(element)[0];
      body = $document[0].body;
      body.appendChild(root);
    
      // trigger initial digest
      $rootScope.$digest();
    }));
    afterEach(function () {
      // clean up
      body.removeChild(root);
    });
    
    1. Plunker。不要使用$animate.addClass测试您的动画,而是使用较低级别的$$animateJs服务。 Angular使用它inside their own tests,我假设绕过上面的检查。 实施例
    2. it('should animate', inject(function ($animate, $$animateJs) {
        // trigger animation
        $$animateJs(element, 'addClass', {
          addClass: 'added-class'
        }).start();
        $animate.flush();
      }));
      

      如果您运行Plunkers并检查控制台,您应该会看到“addClass triggered”消息。我还添加了一些断言。

      这两个解决方案都是hacky和notocumented,如果你的addClass动画执行异步操作(我认为会这样做),两者都会变得更加复杂。不幸的是,我找不到更好的方法来测试JS动画。在过去,我实际上忽略了覆盖范围内的动画代码,因为它很难测试。