Javascript: Loading Template URLs for Testing Angular Components in Karma
A Simple Guide
i. Intro
ii. The Setup
iii. The Fix
iv. Conclusion
Intro:
Trying to use templateUrl and testing with Karma proved to be a nightmare.
This was because templateUrl, as defined within the angular components, paths used a relative path from the index.html file that is served, while injecting these templates through Karma used a relative path stemming from the root of the project directory (or wherever karma.conf.js is placed).
With the templateUrls not being loaded, there was no way to write and run test for angular components I wrote.
I found a couple of (really bad) solutions.
- Move the index.html file to the root of the directory. (Security issues)
- Define templates within the components themself . (Code readability)
- Redefine the templateUrl path everytime you wanted to run a test. (Just don’t)
This problem plagued me for hours, if not days, when trying to set up Karma testing for Angular components and finally came across a solution that I will write down here.
The Setup:
If Karma is installed, please skip to “The Fix” section.
Now, head to your terminal and the root of your project directory then type:
npm install karmanpm install karma-ng-html2js-preprocessorkarma init
You will be asked a series of questions after typing the last command. Make sure you specify all the files you want Karma to load when it asks you too.
For my project, my file structure looked like:
- client
- components
app.js
- templates
app.html
index.html
- server
- db
karma.conf.js
package.jsonand app.js resembled:
angular.module('app')
.component('app', {
controller: 'AppCtrl',
templateUrl: 'templates/app.html'
)}
.controller('AppCtrl', function (...) {...})The Fix:
BEWARE: The following notation will be based upon the above file structure and app component that I have defined. Your experience will most likely vary.
Now head into your karma.conf.js file and add the following properties to the object:
preprocessors: {
'client/templates/*.html': ['ng-html2js']
},It is important to list all of the template html files that you want to test. For this example case, I am loading all my templateUrl files from the templates folder.
Now please add:
ngHtml2JsPreprocessor: {
stripPrefix: 'client/',
moduleName: 'templates'
},“stripPrefix” will remove the ‘client/’ prefix from the templateUrl files loaded from the preprocessors property.
This will ensure that Karma will correctly recognize the templateUrl files relative to the index.html instead of trying to load templateUrl files relative to the root of your directory which causes an error.
“stripPrefix” can be replaced with “prependPrefix” should your file structure call for it. Or you may need neither .
A quick note: “moduleName: ‘templates’” was only added for easier injecting components when writing your tests if you have ngMock installed. Example:
describe('app component', function () {
beforeEach(module('app')); //loads the app module
beforeEach(module('templates')); //loads up all the templateUrls
});You do NOT need to have this property to load templateUrl files correctly.
Conclusion:
Good luck with setting up your Karma tests for Angular!
