簡體   English   中英

AngularJS-單元測試時無法在腳本標記中找到指令模板

[英]AngularJS - Cannot find directive template in script tag when unit testing

我有一個包裝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();
}));

如果可以,請在Chrome中調試您的網站,然后檢查源。 查看您的html文件是否存在帶有不同大小寫的文件夾路徑

我遇到了一個瘋狂的問題,我的咕unt聲/業力設置會將html加載到這樣的路徑中(app / src / Templates / my.html),但是我的$ templateCache正在尋找(app / src / templates / my.html)

問題是套管問題/ Templates vs / templates

同樣在您的測試中,即使加載了html,您可能也必須手動填充模板緩存,這是我由於路徑問題而必須執行的操作

編輯:嘗試使用moduleName

確保您正在使用ngHtml2js預處理器

在業力配置文件中,您可以嘗試使用moduleName選項

ngHtml2JsPreprocessor: {
    moduleName: 'myModule'
}

如果您使用的是require.js

我在項目中使用了require,並且遇到了一個問題,即它沒有填充我的$ templateCache。 看着html2js預處理器在做什么,我修改了模板以在名稱和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
        }

    }));
}

只是一些想法

我對這個問題的解決方案是使用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();
}));

我遇到了同樣的問題, cormacb的回答提供了我需要的提示(非常感謝cormacb !)。

在我的工作方法中,在beforeEach我在html變量text-string中定義<script type="text/template" id="qq-template"> ,然后將html首先附加到document.body 然后,我創建fine-uploader <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 / text定義,並且不需要使用此處其他答案中所使用的任何html2js預處理器大小。

希望這對其他人有幫助。 感謝SO社區提供的所有出色答案!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM