3

I have a directive:

app/controllers/battle.js

angular.module('myModule')
  .controller('myController',
  ['$scope',
  function($scope){
    $scope.sayHello = function(){console.log('hello');};
  }])
  .directive('myDirective', function(){
    return {
      templateUrl: '../views/testView.html'
    }
  });

That directive is called as follows:

app/views/routeOne.html

<my-directive ng-controller='myController'></my-directive>

The directive templateUrl points to a file that looks like:

app/views/testView.html

<div id='testView'>Hello</div>
<div id='eggs'>Here are some eggs.</div>

How do I unit test with karma/jasmine to ensure that the div id in testView.html exists?

Methods tried:

  1. Using ngHtml2Js as per this stackoverflow answer. Reason failed: Unclear on how to access the created module, how the newly created module helps access/query the DOM elements in the testView.html file, unclear what path to use in each of the 4 places testView.html must be pointed to.

  2. Using Html2Js as per this blogpost. Reason failed: Similar to (1).

  3. Accessing the template with jquery.ajax as per this article. Reason failed: angular router prevented me from simply querying straight to the file, though I could access it directly via curl or my browser. Failed on many attempted routes. Probably not only angular router preventing this method from working.

  4. Using $compile as per the angular docs. Reason failed: $compile not found, or, directive not found, or, compiling the directive not returning anything.

Trawling across the internet for how to test an HTML file that's the template for an angular directive yields many different methods, none of which I've managed to make work. I'm happy to use any of the above methods, but I've yet to find a guide that can take me from start to finish in a holistic manner and cover enough of what's happening to actually answer my question. So: how can I test the HTML used by my directive?

Community
  • 1
  • 1
Caleb Jay
  • 2,159
  • 3
  • 32
  • 66

1 Answers1

2

I would suggest solution 1 with some changes.

A small change in directive.

angular.module('myModule')
   .controller('myController',['$scope',function($scope){
         $scope.sayHello = function(){console.log('hello');};
    }])
   directive('myDirective', function(){
      return {
        templateUrl: '../views/testView.html',
        controller: 'myController'
      }
   });

In karma.conf.js

plugins: [
        // some other plugins as well
        'karma-ng-html2js-preprocessor'
    ],
preprocessors: {
     "path/to/templates/**/*.html": ["ng-html2js"]
},

ngHtml2JsPreprocessor: {
    // If your build process changes the path to your templates,
    // use stripPrefix and prependPrefix to adjust it.
    stripPrefix: "app",
    prependPrefix: "..",
    // the name of the Angular module to create
    moduleName: "templates"
},

Now in battel.spec.js //test file

describe('Directive Tests', function () {
    beforeEach(module('templates'));
    beforeEach(module('myModule'));

    var $compile, $rootScope;

    beforeEach(inject(function (_$compile_, _$rootScope_) {
        // The injector unwraps the underscores (_) from around the parameter names when matching
        $compile = _$compile_;
        $rootScope = _$rootScope_;
   }));
  it('Some test', function(){
       var element = $compile("<my-directive></my-directive>")($rootScope);
       $rootScope.$apply();
       expect(element.html()).toContain('Here are some eggs');
  });
});
Zohaib Ijaz
  • 21,926
  • 7
  • 38
  • 60
  • I haven't had a chance to try it yesterday, got the question out just at the end of the day. Trying it now and will let you know, thank you for taking the time to answer. – Caleb Jay Jun 25 '16 at 16:30
  • I'm getting a "module 'templates' is not available!" error from karma. I tried playing around with the stripprefix and prependprefix options, and to go without them because I don't have a build process really at all, but I haven't been able to solve this one. Any thoughts? – Caleb Jay Jun 25 '16 at 17:29
  • @komali_2 Are you using "templates" as module name in karma.conf.js `ngHtml2JsPreprocessor: { moduleName: "templates" },` – Zohaib Ijaz Jun 25 '16 at 17:31
  • yes, but one moment, I just realized that for the past three days and through all my various attempts, I had a second plugins: [] declared at the bottom of my karma config I never saw. After I finish putting a hole in the wall with my head, I'll attempt again and let you know. – Caleb Jay Jun 25 '16 at 18:57
  • for reference, here's the actually repo where I'm trying to implement this. I simplified my example. All the code is in the app folder https://github.com/komali2/langBattle/tree/test – Caleb Jay Jun 25 '16 at 19:01
  • found another error: in my files property in karma config, I hadn't pointed to the html files. Now I'm getting a unexpected request: GET .../ error – Caleb Jay Jun 25 '16 at 19:05
  • Well, the initial issue has been solved. This seems to be an issue with ui-router, and I got the above code to work on a much simpler example that doesn't user router, so I'm marking this as solved. Cheers! – Caleb Jay Jun 25 '16 at 19:10