Testing - SoftwareSandbox/FiAngulartje GitHub Wiki
Introducing a new dev library
After switching to ui-route instead of angulars default ngRoute, none of my tests were working anymore.
Eventhough I used bower to install angular-ui-route with sudo bower install angular-ui-route
, I still had to manually add angular-ui-route.js to the karma.conf.js
like so:
files: [
'bower_components/angular/angular.js',
...
'bower_components/angular-ui-router/release/angular-ui-router.js',
...
'test/spec/**/*.js'
],
Learned
Bower install
does not add the library to your karma.conf.js.
Testing Directives
When you want to test a directive
that uses a file for a templateUrl, your Spec will actually try to http GET your views/directives/directive.html
file. And your test will break with this message:
Error: Unexpected request: GET views/directives/fiproduct.html
No more request expected
at $httpBackend (/.../bower_components/angular-mocks/angular-mocks.js:1225)
Learned
Setup
You'll need to use the ng-html2js preprocessor in your karma.conf.js
file:
files: [
'app/views/directives/*.html'
],
plugins: {
'karma-phantomjs-launcher',
'karma-jasmine',
'karma-ng-html2js-preprocessor'
}
preprocessors: {
'**/*.html': ['ng-html2js']
},
ngHtml2JsPreprocessor: {
stripPrefix: 'app/',
}
The files
property makes sure that our directives are also evaluated by all preprocessors and plugins during our karma run. So we need to make sure that our directives are in there as well.
The preprocessors
property makes sure that all our html files will get process by a module or function called 'ng-html2js'.
The plugins
property contains a set of karma plugins, to which we'll need to add 'karma-ng-html2js-preprocessor'. If we don't we'll get error messages, and at the beginning of our karma run you'll see output that looks like this:
WARN [preprocess]: Can not load "ng-html2js", it is not registered! Perhaps you are missing some plugin?
The ngHtml2JsPreprocessor
property is necessary so that app/ will get stripped in the $httpBackend mock configuration basically. This means that the unexpected request will still be unexpected, even if we would load our directive in our test as a module. Because the mock would be expecting calls to /app/views/directives/... So we tell the preprocessor to strip the app/, making sure that our GET's to our directives are mocked correctly.
Usage in your Directive Specs
beforeEach(module('views/directives/fiproduct.html'));
This looks weird since you want to be loading javascript modules, not html files. This is what the html2js preprocessor does. It will serve your .html files as .js files and then these will get configured into the $httpBackend mock.
Resources
Vojta's simple directive testing repo
The screencast that helped me figure out the stripping of /app
, which got my spec working finally.