ngAnimate 1.4.7 unit test not calling animation functions

南楼画角 提交于 2019-12-10 12:32:34

问题


I've been working from this tutorial and have Googled ad nauseum, but I can't seem to get what appears to be a trivial ngAnimate unit test running.

I have ngAnimate working well in the app. All Angular core libraries are version 1.4.7.

Module

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

Test

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'

I'm sure that the module is being included in the test, but triggering $animate.enter doesn't even get me my log output.

I've tried this with other $animate functions as well and am getting nowhere. Help?


回答1:


After some serious digging into Angular's source code, it appears that the culprit is the internal check areAnimationsAllowed which Angular uses to determine whether to abort the animation early. Among other things, it checks that the node being animated is a descendant of the $rootElement and the document body.

You have two options here.

  1. Plunker. Attach the node you are animating to $rootElement and attach the $rootElement to the body. The latter is necessary because ngMock actually stubs $rootElement with a detached <div> node held in memory. Example:
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. Do not test your animation using $animate.addClass, but instead use the lower-level $$animateJs service. Angular uses it inside their own tests, I assume to bypass the above check. Example:
it('should animate', inject(function ($animate, $$animateJs) {
  // trigger animation
  $$animateJs(element, 'addClass', {
    addClass: 'added-class'
  }).start();
  $animate.flush();
}));

If you run the Plunkers and check the console, you should see your "addClass triggered" message. I have also added a couple assertions.

Both solutions are hacky and undocumented, and both become more involved if your addClass animation does something asynchronous (which I assume it will). Unfortunately, I cannot find a better way to test JS animations. In the past I've actually ignored animation code from coverage because it's so difficult to test.



来源:https://stackoverflow.com/questions/33405666/nganimate-1-4-7-unit-test-not-calling-animation-functions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!