我有一个包含Widen的Fine Uploader实用程序的指令。从功能上来说,它可以完成我想要的一切,但我现在遇到了为它编写单元测试的问题。
Fine Uploader使用在id为'qq-template'的脚本标记中查找的模板。我把它放在模板文件中,该文件在指令返回的对象的templateUrl属性中引用。
我已将Grunt配置为在此文件上运行html2js预处理器并将代码存储在$ templateCache中。我在beforeEach调用中将模板文件包含在单元测试中。
当我运行测试时,我收到错误:
“无法在ID'qq-template'找到模板脚本!”
在我的应用程序中使用此指令时没有问题。显然,我对模板的使用方式有些不了解。有人可以帮忙吗?
指令:
angular.module('ai.upload').directive('fineUploader', function($compile) {
return {
replace: false,
restrict: 'A',
scope: {
validation: '@',
uploadServer:'@'
},
templateUrl: 'source/shared/upload/partials/fine-uploader-template.html',
link: function(scope, element, attrs) { ... }
}
模板文件:
<script type="text/template" id="qq-template">
<div class="qq-uploader-selector qq-uploader">
<div id="totalProgress" class="progress progress-striped active hide">
<div class="progress-bar" role="progressbar"></div>
</div>
<div class="qq-upload-drop-area-selector uploader-drop-zone">
<span class="drop-zone-text" ng-bind="dropZoneText"></span>
<ul class="qq-upload-list-selector qq-upload-list">
<li class="file-container hide">
<div class="qq-progress-bar-container-selector progress">
<div class="qq-progress-bar-selector progress-bar"></div>
</div>
<div class="file-info">
<span class="qq-upload-spinner-selector qq-upload-spinner"></span>
<img class="qq-thumbnail-selector" qq-max-size="50" qq-server-scale>
<span class="qq-upload-file-selector qq-upload-file"></span>
<span class="qq-upload-size-selector qq-upload-size"></span>
</div>
<button class="qq-upload-cancel-selector btn btn-small btn-warning hide" href="#">Cancel</button>
<button class="qq-upload-retry-selector qq-upload-retry btn btn-small hide" href="#">Retry</button>
<button class="qq-upload-delete-selector btn btn-small btn-danger hide" href="#">Delete</button>
<span class="qq-upload-status-text-selector qq-upload-status-text"></span>
</li>
</ul>
<div class="qq-upload-button-selector ai-button-default button-separator select-button">
<div ng-bind="uploadButtonText"></div>
</div>
</div>
<span class="qq-drop-processing-selector qq-drop-processing">
<span class="qq-drop-processing-spinner-selector qq-drop-processing-spinner"></span>
</span>
</div>
单元测试:
describe('aiFineUploader', function() {
var element;
var scope;
beforeEach(module('ai.upload'));
beforeEach(module('source/shared/upload/partials/fine-uploader-template.html'));
beforeEach(inject(function($compile, $rootScope) {
scope = $rootScope;
scope.validation = {
fileExtensions: 'xml',
sizeLimit : '100000000',
acceptFiles: ['text/xml']
};
var html =
' <div fine-uploader' +
' validation = "{{validation}}"' +
' upload-server="mockServer"';
element = angular.element(html);
$compile(element)(scope);
$rootScope.$digest();
}));
答案 0 :(得分:0)
如果可以,请在Chrome中调试您的网站并检查来源。查看是否存在具有不同大小的文件夹路径,用于html文件
我有一个疯狂的问题,我的grunt / karma设置会将html加载到这样的路径中(app / src / Templates / my.html) 但我的$ templateCache正在寻找(app / src / templates / my.html)
问题是套管问题/模板vs /模板
同样在你的测试中,即使html被加载,你也可能需要手动填充模板缓存,这是我因为路径问题而必须做的事情
编辑:尝试使用moduleName
确保您使用的是ngHtml2js预处理器
在您的karma配置文件中,您可以尝试使用moduleName选项
ngHtml2JsPreprocessor: {
moduleName: 'myModule'
}
如果您使用的是require.js
我在我的项目中使用require,并且遇到了一个问题,即它没有填充我的$ templateCache。看看html2js预处理器正在做什么我修改了模板 在name和html周围包装一个对象
TEMPLATE = '(function() {\n' +
' define([], function(){\n' +
' return { name: \'%s\', html: \'%s\' }; \n' +
' });\n' +
'}());\n';
在我的测试中,我刚刚将myHtml.html.js文件添加为我的测试中的依赖项
define(['myHtml.html'], function (myHtml) {
describe('Test', function () {
it('should...', inject(function ($injector, $rootScope, $controller, $compile, $templateCache) {
var $httpBackend = $injector.get('$httpBackend');
$httpBackend.whenGET('/' + myHtml.name).respond(myHtml.html);
var $scope = $rootScope.$new();
var element = $compile('<div my-directive></div>')($scope);
$scope.$digest();
$httpBackend.flush();
expect(element
}
}));
}
只是一些想法
答案 1 :(得分:0)
我对此问题的解决方案是使用angular.element()手动将元素附加到beforeEach块中的文档正文。它现在可在FineUploader查找时使用。该块现在看起来像:
beforeEach(inject(function($compile, $rootScope, $templateCache) {
scope = $rootScope;
scope.validation = {
fileExtensions: 'xml',
sizeLimit : '100000000',
acceptFiles: ['text/xml']
};
scope.onUploadComplete = function(){
return 'onUploadComplete called';
}
scope.updateFileStatus = function(){
return 'updateFileStatus called';
}
var html =
' <div fine-uploader' +
' validation = "{{validation}}"' +
' upload-server="mockServer"'+
' authentication-token="123"'+
' on-submit-file="onSubmitFile(file)"'+
' update-file-status="updateFileStatus(file)"'+
' on-upload-complete="onUploadComplete(response, file)">'+
'</div>';
element = angular.element(html);
$compile(element)(scope);
angular.element(document.body).append(element);
scope.$digest();
}));
答案 2 :(得分:0)
我遇到了同样的问题, cormacb 的回答提供了我需要的提示(非常感谢 cormacb < /强>!)。
在我的工作方法中,在beforeEach
中,我在html变量文本字符串中定义<script type="text/template" id="qq-template">
,然后首先将该html附加到document.body
。然后,我创建精细上传器<div>
,编译并消化它 - 此时qq-template
可用。
var html =
'<script type="text/template" id="qq-template">' +
' <div class="qq-uploader-selector qq-uploader qq-gallery" ng-attr-qq-drop-area-text="{{ dropZoneText }}">' +
' <div class="qq-total-progress-bar-container-selector qq-total-progress-bar-container">' +
// ...
' </div>' +
' </div>' +
'</script>';
angular.element(document.body).append(html);
var element = angular.element('<div fine-uploader></div>');
var compiledElement = _compile(element)(_scope);
_scope.$digest();
此方法对qq-template
使用简单的html /文本定义,并且不需要使用任何html2js预处理器,如此处的其他答案中所使用的那样。
希望这有助于其他人。感谢SO社区提供所有出色的答案!