Writing unit tests using Karma and Jasmine

Loading

Unit testing in AngularJS is primarily done using Karma as the test runner and Jasmine as the testing framework. Karma helps execute tests in multiple browsers, while Jasmine provides a clean syntax for writing test cases.

In this guide, we will cover:

  • Setting up Karma and Jasmine
  • Writing test cases
  • Mocking dependencies
  • Running tests and analyzing results

1. Setting Up Karma and Jasmine

To start writing unit tests, follow these steps:

Step 1: Install Required Packages

Ensure you have Node.js installed, then install Karma and Jasmine globally:

shCopyEditnpm install -g karma karma-cli jasmine-core karma-jasmine karma-chrome-launcher karma-ng-html2js-preprocessor

Step 2: Initialize Karma

Run the following command to set up Karma:

karma init karma.conf.js

This will prompt you to answer some configuration questions. For a typical AngularJS project:

  • Test framework? → Jasmine
  • Use Require.js? → No
  • Which browser? → Chrome
  • Where to find test files? → Use a glob pattern like test/**/*.spec.js

2. Writing Unit Tests in Jasmine

Jasmine provides functions like describe(), it(), and expect() to structure and define test cases.

Basic Syntax

describe('Suite Name', function() {
it('should perform a basic test', function() {
expect(true).toBe(true);
});
});

3. Testing an AngularJS Controller

Assume we have a simple CalculatorController in our AngularJS app:

Controller Code (calculatorController.js)

app.controller('CalculatorController', function($scope) {
$scope.add = function(a, b) {
return a + b;
};
});

Test Case for Controller (calculatorController.spec.js)

describe('CalculatorController', function() {
var $controller, $rootScope;

beforeEach(module('myApp')); // Load the module

beforeEach(inject(function(_$controller_, _$rootScope_) {
$controller = _$controller_;
$rootScope = _$rootScope_;
}));

it('should add two numbers correctly', function() {
var $scope = $rootScope.$new();
var controller = $controller('CalculatorController', { $scope: $scope });

expect($scope.add(3, 5)).toBe(8);
expect($scope.add(-2, 2)).toBe(0);
});
});

4. Testing AngularJS Services

Service Code (mathService.js)

app.service('MathService', function() {
this.multiply = function(a, b) {
return a * b;
};
});

Test Case for Service (mathService.spec.js)

describe('MathService', function() {
var MathService;

beforeEach(module('myApp'));

beforeEach(inject(function(_MathService_) {
MathService = _MathService_;
}));

it('should multiply two numbers correctly', function() {
expect(MathService.multiply(3, 4)).toBe(12);
expect(MathService.multiply(0, 5)).toBe(0);
});
});

5. Mocking Dependencies Using $q and $httpBackend

Service with $http (dataService.js)

app.service('DataService', function($http) {
this.getData = function() {
return $http.get('/api/data');
};
});

Mocking HTTP Requests in the Test (dataService.spec.js)

describe('DataService', function() {
var DataService, $httpBackend;

beforeEach(module('myApp'));

beforeEach(inject(function(_DataService_, _$httpBackend_) {
DataService = _DataService_;
$httpBackend = _$httpBackend_;
}));

it('should fetch data from API', function() {
var mockData = { name: "Test User" };

// Mock HTTP response
$httpBackend.whenGET('/api/data').respond(200, mockData);

var result;
DataService.getData().then(function(response) {
result = response.data;
});

$httpBackend.flush(); // Resolve the HTTP request

expect(result).toEqual(mockData);
});
});

Why Use $httpBackend?

  • Simulates API calls without making real HTTP requests.
  • Controls responses and avoids network dependency in tests.

6. Running Tests

Once test cases are written, run Karma:

karma start karma.conf.js

To auto-run tests on file changes, enable auto-watch in karma.conf.js:

autoWatch: true

7. Code Coverage with Karma and Istanbul

To generate a test coverage report:

  1. Install the coverage plugin: npm install --save-dev karma-coverage
  2. Update karma.conf.js: reporters: ['progress', 'coverage'], preprocessors: { 'src/**/*.js': ['coverage'] }, coverageReporter: { type: 'html', dir: 'coverage/' }
  3. Run Karma and check the coverage/ folder for reports.

Leave a Reply

Your email address will not be published. Required fields are marked *