0

I have a directive that dynamically adds a loading indicator to html element. Here is the directive:

return {
    restrict: 'EA',
    scope: true,
    replace: true,
    transclude: true,
    template: '<div ng-transclude></div>',
    link: function(scope, element, attr) {
        var loadingExpression = attr["loadingIndicator"] || attr["loadingState"];

        scope.$watch(loadingExpression, function (isLoading) {
            scope["isLoading"] = isLoading;
        });

        $templateRequest('/templates/loading-indicator/indicator.html').then(function(template) {
            $compile(template)(scope).appendTo(element);
        });

        // Apply position:relative to parent element if necessary
        var position = element.css('position');
        if (!position || position === 'static') {
            element.css('position','relative');
        }
    }
};

Works as expected.

Now I want to write a simple tests for that directive to see if the loading spinner (part of the indicator.html template) is added to the DOM:

describe('loadingIndicatorDirective', function () {
    var element, $scope;

    beforeEach(function () {
        module('loadingIndicator');

        inject(function ($rootScope, $compile) {
            element = angular.element(
                '<div>' +
                    '<div loading-indicator="true">' +
                        '<p>Lorem Ipsum ...</p>' +
                        '<p>TEST TEST TEST</p>' +
                    '</div>' +
                '</div>'
            );

            $scope = $rootScope;
            $compile(element)($scope);
            $scope.$digest();
        })
    });

    it('should create a loading spinner', function () {
        var spinner = element.find('.loading-indicator');

        expect(spinner.length).toBe(1);
    });
});

When running the test, I get the error: "Error: Unexpected request: GET /templates/loading-indicator/indicator.html". I want to have a test, that uses the actual template that I am appending in the directive. Isn't that possible?

mAtZ
  • 89
  • 2
  • 8
  • Seems like you need to request that template in the test too. I'm guessing inject `$templateRequest` and take if from there. – dcodesmith Feb 06 '15 at 11:08

1 Answers1

1

It's because Angular tries to fetch the HTML content with an HTTP GET request. However, in a unit-testing environment, you cannot actually make HTTP requests because you don't have a full web server environment.

To solve this problem, you have to avoid direct GET requests and replace them with a pre-processor that will compile Angular templates into JavaScript strings. For instance, html2js does this job.

You can follow one of these html2js how-to:

Other StackOverflow users already had some errors with html2js. You can also check these questions:

Community
  • 1
  • 1
Pierre-Yves O.
  • 508
  • 3
  • 15