on software development (possibly other stuff)

Testing Angular Directives with Templates on Karma and Browserify

No comments
Directives are the cornerstone of every Angular application. And templates help keep their behavior separate from the presentation.

Karma works well with Angular and is an essential tool for running tests against a number of supported browsers.

Lastly, Browserify helps preserve sanity while maintaining JavaScript modules (similar to Node.js i.e. CommonJS spec).

Sadly, integrating all four concepts is not a straightforward process. Below is a rough guide on how to achieve this.

1. Install karma-browserifast and karma-ng-html2js-preprocessor
$ npm install karma-browserifast --save-dev
$ npm install karma-ng-html2js-preprocessor --save-dev
The package karma-browserifast enables Browserify support on Karma. While karma-ng-html2js-preprocessor converts HTML templates to JavaScript and loads them as an Angular module.

2. Configure Karma
module.exports = function (config) {
  config.set({
    files: [
      'node_modules/angular/angular.js',
      'src/**/*.html'
    ],

    browserify: {
      files: [
        'test/unit/**/*.js',
      ],
      debug: true
    },

    preprocessors: {
      '/**/*.browserify': ['browserify'],
      'src/**/*.html':    ['ng-html2js'],
    },

    ngHtml2JsPreprocessor: {
      moduleName: 'karma.templates'
    },

    frameworks: ['jasmine', 'browserify'],
    browsers:   ['Chrome'],
    reporters:  ['spec'],
    logLevel:   'info',
    autoWatch:  true,
    colors:     true,
  });
};
Lines 4 and 5 loads the HTML templates into Karma. Because they will be pre-processed by karma-ng-html2js-preprocessor, they will eventually get loaded as JavaScript files. Note that even if Angular will be included as part of the Browserify bundle, it is important to load it explicitly. Otherwise, the templates cannot be made available to Angular.

Line 10 tells karma-browserifast to include all unit tests as a Browserify bundle. This makes it possible for unit tests to execute JavaScript modules using the "require" keyword.

Line 21 tells karma-ng-html2js-preprocessor to load the JavaScript templates as an Angular module named "karma.templates". This will later be used in unit tests to allow testing of directives that use templates.

3. Write the unit tests
require('../src/app');
require('angular-mocks/angular-mocks');
describe('myDirective', function () {
  var scope, element;

  beforeEach(function () {
      angular.mock.module('karma.templates');
      angular.mock.module('myModule');
      angular.mock.inject(function ($rootScope, $compile) {
          scope   = $rootScope.$new();
          element = $compile('<div my-directive></div>')(scope);

          scope.$digest();
      });
  });

  it('does something', function () {
    expect(1).toBe(1);
  });
});
Lines 1 and 2 demonstrates the capability of a Karma-based unit test to load modules via "require".

Line 7 loads the generated JavaScript templates as an Angular module; without this, the directive will not compile because the template cannot be fetched.

No comments :

Post a Comment