Unit Test AngularJS directive mit templateUrl in VS und Chutzpah


Damit meine eigenen Direktiven übersichtlich bleiben, lege ich die Templates immer in einer extra HTML Datei ab und verwende entsprechend die “templateUrl” in meinen Direktiven.

Leider ist das Füllen des AngularJS Templatecaches mit Chutzpah ein klein wenig umständlicher als wenn man Karma und dem ng-html2js Präprozessor zum füllen des AngularJS Templatecaches verwendet. Da ich bei meiner Testumgebung aber nicht mehr Tools als notwendig einsetzen möchte und ich aktuell Chutzpah verwende, stelle ich im Folgenden einen möglichen Lösungsweg vor.

(Wie man ChutzPah in VS verwendet habe ich bereit hier erläutert.)

Als Grundlage verwende ich eine einfache Direktive mit TemplateUrl

angular.module("testTemplateDirective", [])
    .directive("testTemplate", function() {
        return {
            restrict: 'A',
            replace: true,
            templateUrl: 'ScriptsApp/directives/Templates/testTemplate.html'
        }
});

dazu gehört das folgende HTML Template “testTemplate.html” im Root Element muss eine eindeutige CSS Klasse hinterlegt werden die das Template identifiziert (leider notwendig für die Unit Tests).

<div class="row templateTestTemplate">
    <div class="col-lg-12">
        <h1>Tempalte Test</h1>
    </div>
</div>

Dazu muss man wissen das ChutzPah die Möglichkeit bietet neben den Referenzen zu den Script Dateien im Header des Tests ebenfalls den Pfad zu “templates” anzugeben mit einem “template” Tag.

/// <template path="../../MvcAngularJs1_3/ScriptsApp/directives/Templates/testTemplate.html" />
/// <reference path="../../mvcangularjs1_3/scripts/jquery-2.1.1.js" />
/// <reference path="../../mvcangularjs1_3/scripts/angular.js" />
/// <reference path="../../mvcangularjs1_3/scripts/angular-mocks.js" />
/// <reference path="../../mvcangularjs1_3/scriptsapp/directives/testtemplatedirective.js" />

... Unit Test

Der Komplette Inhalt des Templates wird dann in der HTML Testdatei eingefügt und kann über jQuery und unserer eindeutigen CSS Klasse ermittelt werden.

Da AngularJS immer erst prüft ob das Template bereits im TemplateCache enthalten ist, müssen wir unser Template nur noch manuell dem TemplateCache hinzufügen. Als Key wird hier die aufzurufende TemplateUrl verwendet. In meinem Beispiel wird der Key “ScriptsApp/directives/Templates/testTemplate.html” von AngularJS verwendet.

 var template = jQuery(".templateTestTemplate")[0].outerHTML;
 $templateCache.put("ScriptsApp/directives/Templates/testTemplate.html", template);

Wenn das Template einmal dem TemplateCache hinzugefügt wurde, ist der Rest des Unit Tests für Direktiven so wie jeder andere Unit Tests für Direktiven.

ACHTUNG: Der Unit Tests ist nur erfolgreich, wenn der Test mit ChutzPah ausgeführt wird. Wenn der Unit Test mit Resharper ausgeführt wird, dann schlägt der Unit Test fehl, denn Resharper kennt das “template” Tag nicht und fügt damit auch keinen HTML Code in der Testdatei ein wie ChutzPah.

Der komplette Test sieht dann folgendermaßen aus

/// <template path="../../MvcAngularJs1_3/ScriptsApp/directives/Templates/testTemplate.html" />
/// <reference path="../../mvcangularjs1_3/scripts/jquery-2.1.1.js" />
/// <reference path="../../mvcangularjs1_3/scripts/angular.js" />
/// <reference path="../../mvcangularjs1_3/scripts/angular-mocks.js" />
/// <reference path="../../mvcangularjs1_3/scriptsapp/directives/testtemplatedirective.js" />

var siteRoot = "";

angular.module("app.testtmplate", ["testTemplateDirective"]);

describe("Unit Tests für die Direktive 'testTemplateDirective' ", function() {
    var $rootScope, $compile;

   beforeEach(function() {
        //Unsere Main App laden
        module('app.testtmplate');
        inject(function(_$rootScope_, _$compile_) {
            $rootScope = _$rootScope_;
            $compile = _$compile_;
        });
    });

    describe('Tests für Direktive "testTemplateDirective"', function () {
        beforeEach(function () {
            inject(function ($templateCache) {
                //mit jQuery unseren HTML Code inkl. des Selectors ermitteln.
                var template = jQuery(".templateTestTemplate")[0].outerHTML;
                $templateCache.put("ScriptsApp/directives/Templates/testTemplate.html", template);
            });
        });

        it('Es wurde ein H1 mit dem Text "Template Test" angelegt', function () {
            var element = $compile("<div><div test-template></div>")($rootScope);
            $rootScope.$digest();

            expect(element.html()).toContain("<h1>Tempalte Test</h1>");
            expect(element.find("h1").length).toBe(1);
        });
    });
})
Advertisements

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s