ngAnimate 1.4.7单元测试未调用动画功能 [英] ngAnimate 1.4.7 unit test not calling animation functions
问题描述
我一直在通过本教程进行工作,谷歌广告的恶作剧,但我似乎无法获得似乎是微不足道的 ngAnimate
单元测试运行。
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.
我的 ngAnimate
在应用中运行良好。所有Angular核心库的版本均为1.4.7。
I have ngAnimate
working well in the app. All Angular core libraries are version 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
输出。
I'm sure that the module is being included in the test, but triggering $animate.enter
doesn't even get me my log
output.
我也尝试过使用其他 $ animate
函数,但是却一无所获。
I've tried this with other $animate
functions as well and am getting nowhere. Help?
推荐答案
认真研究Angular的源代码后,罪魁祸首似乎是内部检查 areAnimationsAllowed
。除其他事项外,它检查正在设置动画的节点是否是 $ rootElement
和文档正文的后代。
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.
您在这里有两个选择。
- 柱塞。 将要设置动画的节点附加到
$ rootElement
并将$ rootElement
附加到正文 。后者是必需的,因为ngMock
实际上将$ rootElement
存根带有独立的< div>
节点保存在内存中。 示例:
- Plunker. Attach the node you are animating to
$rootElement
and attach the$rootElement
to the body. The latter is necessary becausengMock
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);
});
- 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();
}));
如果运行Plunkers并检查控制台,则应该看到 addClass触发消息。我还添加了一些断言。
If you run the Plunkers and check the console, you should see your "addClass triggered" message. I have also added a couple assertions.
这两种解决方案都是骇人听闻的,而且没有文档记录,如果您的 addClass
动画做一些异步的事情(我想是的)。不幸的是,我找不到更好的方法来测试JS动画。过去我实际上从覆盖范围中忽略了动画代码,因为它很难测试。
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.
这篇关于ngAnimate 1.4.7单元测试未调用动画功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!