【发布时间】:2017-01-05 17:11:32
【问题描述】:
我有以下指令告诉我我尝试使用的图像是否已成功加载:
return {
restrict: 'A',
scope: {
imageLoad: '@'
},
link: function(scope, element, attrs) {
attrs.$observe('imageLoad', function (url) {
var deferred = $q.defer(),
image = new Image();
image.onerror = function () {
deferred.resolve(false);
};
image.onload = function () {
deferred.resolve(true);
};
image.src = url;
return deferred.promise;
});
}
};
然后我想做的就是测试image.onerror 和image.onload 的两个简单测试,但我似乎只进入了错误功能,这是我目前所拥有的:
compileDirective = function() {
var element = angular.element('<div data-image-load="http://placehold.it/350x150"></div>');
$compile(element)(scope);
$rootScope.$digest();
return element;
};
beforeEach(inject(function (_$compile_, _$rootScope_) {
$compile = _$compile_;
$rootScope = _$rootScope_;
scope = $rootScope.$new();
}));
it('should do something', function() {
var compiledElement, isolatedScope;
compiledElement = compileDirective();
isolatedScope = compiledElement.isolateScope();
expect(true).toBe(true);
});
显然这个测试通过了,因为它只是期望 true 为 true,但是就覆盖率而言,这进入了 onerror 函数,所以我需要以某种方式测试 deferred.promise 是否应该返回 false。
所以最终是一个两部分的问题,我如何获得 deferred.resolve 的结果?
其次,我如何进入 onload 功能?
我环顾四周,看到了一些添加以下内容的建议:
element[0].setAttribute('imageLoad','http://placehold.it/350x150');
$compile(element)(scope);
element.trigger('imageLoad');
并将data-image-load="" 留空,但似乎没有任何运气,任何建议都会很棒。
【问题讨论】:
-
这与您的问题无关,但是您使用
attrs.$observe有什么特殊原因吗?现在您可以删除它并将url替换为scope.imageLoad。现在传递给$observe的匿名函数只是返回了promise,但是没有人能够看到结果。该指令的重点是什么?它应该如何使用? -
@tasseKATT 实际应用程序中的图像路径基本上是动态的,因此可能会发生变化,因此需要重新触发。承诺确保它已加载,如果失败,我将提供后备图像,我从上面的示例中省略了一些代码,其中我使用 element.css(背景图像)设置了后备图像
-
那么指令本身是唯一对承诺结果做出反应的指令吗?
-
你能展示一下如何使用 promise 的结果来设置回退吗?
-
image.onerror = function () { deferred.resolve(false); element.css({ 'background-image': 'url(' + fallback + ')' }); };
标签: angularjs unit-testing angularjs-directive karma-jasmine