AngularJS:单元测试指令w/Promise从服务返回



我有一个指令,它使用服务,调用返回promise的服务的方法,并在子序列'then'中修改DOM(下面是myTestDirective)。

我正在尝试对这个指令进行单元测试,当我运行测试时,"then"中没有任何内容被调用:promise被拒绝还是解析没有传播?

我遵循了这篇文章中的所有步骤来设置我的单元测试

当我在浏览器中加载指令时,我会看到两条消息,OUTSIDE D3然后INSIDE D3,正如您所期望的那样。

然而,在单元测试中,元素只使用第一条消息更新,如下所示:
<my-test-directive>***OUTSIDE D3***</my-test-directive>
在浏览器中,我看到了这两条消息。

有人知道这里发生了什么吗?我需要注入mock或spy吗?在脚本标记完成加载之前运行测试,这是异步问题吗?我看到单元测试正在访问d3.v3.js,所以脚本标记似乎发生了。我还对d3Service进行了单独的单元测试,它很有效。偶尔我会看到正确的结果,而不会改变测试。

我看到了这个问题的线索,但无法理解如何将其应用于我的情况:Angularjs承诺在单元测试中无法解决

这是代码:

d3服务

var d3 = angular.module('d3', []);
d3.factory('d3Service', ['$document', '$q', '$rootScope', '$window',
function($document, $q, $rootScope, $window) {
var d = $q.defer();
function onScriptLoad() {
$rootScope.$apply(function() { d.resolve(window.d3); });
}
var scriptTag = $document[0].createElement('script');
scriptTag.type = 'text/javascript'; 
scriptTag.async = true;
scriptTag.src = 'lib/d3.v3.js';
scriptTag.onreadystatechange = function () {
if (this.readyState == 'complete') onScriptLoad();
}
scriptTag.onload = onScriptLoad;
var s = $document[0].getElementsByTagName('body')[0];
s.appendChild(scriptTag);
return {
d3: function() { return d.promise; }
};
}]);

指令

var myDirectives = angular.module('myDirectives', ['d3']);
myDirectives.directive('myTestDirective', ['d3Service', '$window', 
function(d3Service, $window) {
return {
restrict: 'EA',
link: function(scope, ele, attrs) {
var f = angular.element(ele[0])
f.append('**OUTSIDE D3***')
d3Service.d3().then(function(d3){    // Nothing here runs at all.
var e = angular.element(ele[0])  // In browser it works, but
e.append('***INSIDE D3***')      // not in the unit test.
})
}
}           
}])

单元测试

describe('Test Directive', function(){
var $scope, elem, compiled, html;
beforeEach(function (){      
module('myDirectives');    
html = '<my-test-directive></my-test-directive>'; 
inject(function($compile, $rootScope) {
$scope = $rootScope;
elem = angular.element(html);
compiled = $compile(elem)($scope);
$scope.$digest();      
});
});   
it('should create an svg element with its data', function(){
console.log(elem) //outputs the element with only ***OUTSIDE D3***
})
})

感谢您提供任何提示或信息!!!!!

我所做的是在我的karma.conf中加载d3.v3.js,然后在单元测试中创建mockd3Service,返回promise。如果有人知道更好的解决方案,请告诉我。

以下是正在运行的新单元测试:

describe('d3 Directives', function(){
var $compile, $rootScope, $window, mockd3Service, $q, html, element, data;
//setup test
beforeEach(function(){
mockd3Service = {}
module('myDirectives')
module(function($provide){
$provide.value('d3Service', mockd3Service)
})
inject(function(_$compile_, _$rootScope_, _$window_, _$q_) {
$window = _$window_;
$compile = _$compile_;
$rootScope = _$rootScope_;
$q = _$q_
});
mockd3Service.d3 = function() {
var deferred = $q.defer();
deferred.resolve($window.d3)
return deferred.promise;
}
});
//run test
it('make test', function(){
html = '<my-directive data="testData"></my-directive>'
element = angular.element(html)
element = $compile(html)($rootScope)        
$rootScope.testData = somedata
$rootScope.$digest();
expect(element...)
})
})

最新更新