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.