Testing an AngularJS Directive
Project tools
sudo npm install -g yo grunt-cli bower karma
Yeoman generators:
sudo npm install -g generator-angular generator-karma
(thanks to @amscotti for the heads up on these).
Create the project
mkdir directive-example && cd $_
yo angular
Configure Karma
Open the karma.conf.js file and make the following changes (any changes to this file require you to restart Karma):
Base path
To enable Karma to use the correct template path and have the directive load template file you will need to change the basePath:
basePath = 'app';
File patterns
Amend the paths to reflect the newly defined basePath:
files = [
JASMINE,
JASMINE_ADAPTER,
'components/angular/angular.js',
'components/angular-mocks/angular-mocks.js',
'scripts/*.js',
'scripts/**/*.js',
'views/**/*.html',
'../test/mock/**/*.js',
'../test/spec/**/*.js'
];
Compiling templates
Templates need to be compiled to javascript otherwise you will get a parse error on running Karma. The html2js preprocessor is the solution and simply requires adding the following to your karma.conf.js (this is based on you storing template files within a directory in views):
preprocessors = {
'views/**/*.html': 'html2js'
};
Auto watch
This is a really cool part of Karma where you can enable watching files and then auto executing tests as you develop:
autoWatch = true;
Optional
I use PhantomJS to run the Angular tests as opposed to relying on a browser such as Chrome.
Change the browser for running tests to PhantomJS:
browsers = ['PhantomJS'];
Create a directive
yo angular:directive albums
Start Karma
To start Karma which will also auto run the tests when we update the files use:
karma start
You should now see that two tests have been executed successfully:
Executed 2 of 2 SUCCESS (0.284 secs / 0.015 secs)
Create a failing test
https://gist.github.com/newtriks/5472834
(Our list is sourced from the crazy talented Busdriver!)
Let's fix the first error we see:
Error: No module: views/templates/albums.html
Build a simple template
mkdir -p app/views/templates
touch app/views/templates/albums.html
Our test is still failing, let's add the new template to the albums.js directive, change the line of code declaring the template to:
templateUrl: 'views/templates/albums.html',
The test will still fail as we are not creating a list within the template. Let's do that now by adding the following to the albums.html:
<ul><li>{{title}}</li></ul>
And update the albums.js directive as follows:
https://gist.github.com/newtriks/5473029
Word! The test passes. Let's add another test to check the first album in the list has the correct title.
it("should display the correct album title for the first item in the albums list", function() {
var list = element.find('li');
expect(list.eq(0).text()).toBe('Memoirs of the Elephant Man');
});
The test fails. Let's add the title attribute to the directives scope in albums.js:
https://gist.github.com/newtriks/5473047
Sweet, the test's are passing again.
All the source to this project can be found on Github.
Full article can be read here: http://newtriks.com/2013/04/26/how-to-test-an-angularjs-directive/
Written by Simon Bailey
Related protips
1 Response
very comprehensive and well written