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.
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.
Thanks to pkozlowski.opensource for leading me in the right direction!
For anyone wondering how I solved it:
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.