我编写了一个指令,它将有条件地添加一个我在Angular< ngIf指令之后建模的包装元素。该指令在生产中运行时效果很好,但在尝试添加单元测试时,$ animate.enter函数从不调用我的回调函数。这会导致我的所有单元测试失败,因为它假定包装器不在那里。
我使用Angular.js版本1.2.16并加载ngMock和ngAnimate进行单元测试。该代码触发ngAnimate enter函数,但它从不触发回调。
您可以查看代码here,只需取消注释appSpec.js脚本标记,该指令就不再有效。
现在有人如何触发$ animate.enter在单元测试中调用我的回调函数?
addWrapperIf.js
angular.module('myModule', ['ngAnimate'])
.directive('addWrapperIf', ['$animate', function($animate) {
return {
transclude: 'element',
priority: 1000,
restrict: 'A',
compile: function (element, attr, transclude) {
return function ($scope, $element, $attr) {
var childElement, childScope;
$scope.$watch($attr.addWrapperIf, function addWrapperIfWatchAction(value) {
if (childElement) {
$animate.leave(childElement);
childElement = undefined;
}
if (childScope) {
childScope.$destroy();
childScope = undefined;
}
// add the wrapper
if (value) {
childScope = $scope.$new();
transclude(childScope, function (clone) {
childElement = clone
$animate.enter(clone, $element.parent(), $element);
});
}
// remove the wrapper
else {
childScope = $scope.$new();
transclude(childScope, function (clone) {
$animate.enter(clone, $element.parent(), $element, function() {
childElement = clone.contents();
clone.replaceWith(clone.contents());
});
});
}
});
}
}
};
}]);
addWrapperIfSpec.js
var expect = chai.expect;
describe('addWrapperIf', function () {
var $template;
var $compile;
var $scope;
beforeEach(window.module('myModule'));
beforeEach(inject(function(_$compile_, $rootScope){
$compile = _$compile_;
$scope = $rootScope.$new();
}));
function compileDirective(template) {
$template = $compile(template)($scope)[0];
$scope.$apply();
}
it('should output the correct values with default options', function() {
compileDirective('<div add-wrapper-if="false"><span>child</span></div>');
console.log($template); // <div add-wrapper-if="false"><span>child</span></div>
});
});
答案 0 :(得分:2)
所以我弄清楚你要做什么。我挖掘代码并发现在ngAnimate中它将回调函数推送到$$asyncCallback
。 $$asyncCallback
有一个flush
函数,可以调用任何推送到它上面的函数。要让$animate.enter
触发回调,您必须将$$asyncCallback
注入单元测试,然后调用$$asyncCallback.flush()
。然后,这将运行您的回调函数。
您可以在此Plunker中看到这一点。