2

I am using Jasmine Standalone to test my Angular directories,

SimpleDirective.js

var app = angular.module("myApp", []);

app.controller('SimpleDirectiveController', function($scope) {
    $scope.customer = {
      name: 'Igor',
      address: '123 Somewhere'
    };
});

app.directive('helloWorld', function() {
    return {
        restrict: 'AE',
        replace: true,

        // Isolate scope:
        // separate the scope inside a directive from the scope outside, and then map the outer scope to a directive's inner scope. 
        scope: {
            customerInfo: '=info'
        },

        //templateUrl points to an external html template.
        templateUrl: 'fixture/hello.html'
    };
});

fixture/hello.html,

<div class="customer"><b>Hello</b> {{customerInfo.name}}</div>

SimpleDirectiveSpec.js,

describe("simpleDirective Test ", function(){

    // Boilerplate starts from here...
    var compile, scope, element;

    // Name of the module my directive is in.
    beforeEach(module('myApp'));

    // The external template file referenced by templateUrl.
    beforeEach(module('fixture/hello.html'));

    beforeEach(inject(function($compile,$rootScope) {

        compile = $compile;
        scope = $rootScope;

        element = angular.element('<div data-hello-world info="customer"></div>');
        compile(element)(scope);
        scope.$digest();
    }));
    // ...Boilerplate ends here

    it('renders the customer template', function() {
        var customer = element.find('.customer');
        expect(customer.length).toBe(1);
    });

});

I get this error,

Error: [$injector:modulerr] Failed to instantiate module fixture/hello.html due to: [$injector:nomod] Module 'fixture/hello.html' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.

Any ideas What I have missed?

Run
  • 54,938
  • 169
  • 450
  • 748

2 Answers2

3

You should create a module for your template and put your template html into templateCache.

It should look like this:

angular.module("fixture/hello.html", []).run(["$templateCache", function($templateCache) {
  $templateCache.put("fixture/hello.html",
    "<div class=\"customer\"><b>Hello</b> {{customerInfo.name}}</div>");
}]);

If you are testing with Karma, there is an automation karma module for this purpose called ng-html2js.

halilb
  • 4,055
  • 1
  • 23
  • 31
  • 1
    Well, it should be loaded in your test browser. So, try putting it to SimpleDirectiveSpec.js for now. If it works, then you should checkout ng-html2js to automatically inject it to your test browser. – halilb Nov 06 '14 at 08:10
  • 1
    And if you are using Grunt, you can use this module: https://github.com/karlgoldstein/grunt-html2js – halilb Nov 06 '14 at 08:13
  • Thanks. I put it in SimpleDirectiveSpec.js, then it fails my test of `it('renders the customer template', function() { var customer = element.find('.customer'); expect(customer.length).toBe(1); });` – Run Nov 06 '14 at 08:15
  • 1
    Are you using jQuery in this project? If not, jqLite find method is limited to lookups by tag name. Check here: http://stackoverflow.com/questions/17283697/angularjs-how-to-find-using-jqlite – halilb Nov 06 '14 at 08:18
  • 1
    So glad I found this post. I have been struggling trying to load directives from templateUrl for like 6 hours. The ng-html2js preprocessors would not work for me. Thanks for the answer! – BradStell Jul 20 '16 at 20:41
1

I assume you are using karma html pre-processor for html template https://github.com/karma-runner/karma-ng-html2js-preprocessor. Make sure that module generated have the path name that matches the module name you are declaring 'fixture/hello.html'.

You can verify the files by opening chrome developer console and check the source tab, the modules would be loaded as js file. Make sure that the name of the module generated match.

Chandermani
  • 42,589
  • 12
  • 85
  • 88