Kenneth Lynne
Kenneth Lynne

Reputation: 15579

Testing directives that uses templates

How can i unit test directives that use templateUrl to load templates?

Since $httpBackend is a mock, it will not load templates either. I would like to be able to use something like

$httpBackend.whenGET(/^\/views\//).passThrough();

and let it actually get the templates, but I haven't figured out how to do this correctly.

I think I have something confused regarding how to unit test directives. Disclaimer: I have no experience testing, or using jasmine nor testacular.

Any help is appreciated.

Upvotes: 6

Views: 2031

Answers (2)

Kenneth Lynne
Kenneth Lynne

Reputation: 15579

Thanks to pkozlowski.opensource for leading me in the right direction!

For anyone wondering how I solved it:

  1. Add https://npmjs.org/package/grunt-angular-templates to your project.
  2. Add a grunt build task to compile all your templates into a js file.

This JS file will now register a module (name can be configured in the gruntfile).

In all your tests dependant on templates you have to load the this module.

Example test:

'use strict';

describe('Component: comments', function() {
  beforeEach(module('studentportalenApp'), module('app.templates'));

  var element;

  it('should render an error message if type is not recognized', inject(function($rootScope, $compile) {
    element = angular.element('<comments></comments>');
    element = $compile(element)($rootScope);
    expect(element.html()).toBe('Comments directive type not recognized.');
  }));
});

Be careful to get your views using the exact same url as defined in the app.templates module. I.e. /views/ and not views/, or else it will not match up with the template cache paths and fire of the request anyways.

Upvotes: 4

pkozlowski.opensource
pkozlowski.opensource

Reputation: 117370

IMO the easiest way of testing directives that depend on templates (referenced by the templateUrl) is to put those templates in the $templateCache up-front. Usually this is done by the build process.

In more details: each template markup is converted to the JavaScript code and put into the $templateCache. Also, a AngularJS module is generated (with a name of a module being path to a template).

By applying this technique we've got only JavaScript files to deal with and we don't need to mock any HTTP calls. The downside is that you need an additional build step.

I believe that originally this technique was popularized by the excellent repository by Vojta Jina: https://github.com/vojtajina/ng-directive-testing where you can see templates preparation here and the actual test referencing a module with a template preload here.

Upvotes: 8

Related Questions