Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing directives with template URL

I'm trying to test an angularJS directive that uses a templateURL. For the life of me I can't get the compiler to actually load the templateURL, even when it has been put into the templateCache. I realize karma preprocesses all the template contents and creates modules for each that preloads the templateCache, but I expected that this would have been equivalent.

Here is a http://jsfiddle.net/devshorts/cxN22/2/ that demonstrates whats going on.

angular.module("app", [])
.directive("test", function(){
    return {
        templateUrl:"some.html",
        replace:true
    }
});

//--- SPECS -------------------------

describe("template url test", function() {
    var element,  scope, manualCompiledElement;

    beforeEach(module('app'));

    beforeEach(inject(function($rootScope, $controller, $compile, $templateCache){
        $templateCache.put("some.html", "<div>hello</div>");

        scope = $rootScope.$new();

        element = $compile(angular.element('<test></test>'))(scope);

        manualCompiledElement = $compile(angular.element($templateCache.get('some.html')))(scope);

        scope.$digest();        
    }));

    it("has hello", function() {
        expect(element.text()).toContain('hello');
    });

    it("template cache has contents", function(){
        expect(manualCompiledElement.text()).toContain('hello');
    });       
});

What am I missing?

like image 948
devshorts Avatar asked Nov 29 '25 06:11

devshorts


1 Answers

I realise you no longer necessarily need to know, but it looks to me like there are two problems contributing to this.

The first was pointed out by @Words-Like-Jared. You are defining the directive as restricted to attributes (default) but using it as an element. So you need restrict: 'E'.

The second problem is that your template is never actually retrieved and your compile/link never completes. The request for the contents of the template within the directive are asynchronous so a digest on the root scope is needed to resolve the promise and return them, similar to this answer for another question.

When you perform your manual compilation, the results are not asynchronous and the template is retrieved immediately. Actually the compilation in your manual compilation doesn't do a lot as you are compiling the contents of your template, which doesn't have any directives in.

Now at the end of your beforeEach where you use

$scope.$digest()

you are digesting on the current scope and its children. When you use $rootScope.$digest() or $scope.$apply() you will perform a digest across all scopes. So changing this to

$rootScope.$digest()
// or
$scope.$root.$digest()

in the line after your compilation means both of your tests will now pass. I have updated the fiddle here.

like image 165
Andyrooger Avatar answered Nov 30 '25 20:11

Andyrooger



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!