Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking AngularJS module dependencies in Jasmine unit tests

I'm attempting to unit test controller code inside a module that takes other modules as dependencies, but haven't been able to figure out how to mock them properly.

I'm using the Jasmine Framework and running my tests with Karma (Testacular).

Module Code

var app = angular.module('events', ['af.widgets', 'angular-table']);  app.controller('eventsCtrl', function([dependencies]){     $scope.events = [];     ... }); 

Spec Code

describe('events module', function(){     var $scope,         ctrl;      beforeEach(function(){         angular.mock.module('af.widgets', []);         angular.mock.module('angular-table', []);         module('events', ['af.widgets', 'angular-table']);     });      beforeEach(inject(function($rootScope, $controller){         $scope = $rootScope.new();         ctrl = $controller('NameCtrl', {             $scope: $scope,         });     }));      it('should have an empty events array', function(){         expect($scope.events).toBe([]);     }) }); 

The error I'm getting is Karma is "no module af.widgets", so obviously I'm not mocking the module dependencies right. Any hints?

like image 306
fscof Avatar asked Jul 09 '13 17:07

fscof


People also ask

Should unit test mock dependencies?

Correct. You should mock things that depend on anything persistent or external in order to prevent the test from depending on anything persistent or external.

Is mocking a dependency injection?

Dependency injection is a way to scale the mocking approach. If a lot of use cases are relying on the interaction you'd like to mock, then it makes sense to invest in dependency injection. Systems that lend themselves easily to dependency injection: An authentication/authorization service.

What is mocking in unit testing Angular?

Introduction. Mocking is a great idea for testing Angular apps because it makes maintenance easier and helps reduce future bugs. There are a few complex tools, such as XUnit, for mocking an Angular CLI project. You can execute the mocking methods described in this guide only if you use vanilla Jasmine + Angular Testbed ...

What is dependency mocking?

Mock the dependencies Unit testing is born to test the behavior of a single component — SUT — without caring of its dependencies. The purpose of mocking the dependencies is to keep the SUT isolated from external objects.


2 Answers

If you want to mock a module that declare one or more services I have used this code:

beforeEach(function(){     module('moduleToMock');     module(function ($provide) {         $provide.value('yourService', serviceMock);     }); }); 

This is useful if the service you want to mock is also a service that you want to unit test (in another jasmine describe). The solution proposed by fscof is fine but you cannot create a unit test for the angular-table module.

like image 194
Davide Icardi Avatar answered Oct 15 '22 20:10

Davide Icardi


Here's what I figured out:

I wasn't loading any 'angular-table' modules in my karma.conf.js file, hence the error. This was intentional at first as I wanted to test the 'events' module without the actual table module.

I was able to easily mock the 'angular-table' module by creating a new file in my test folder called 'mocks/angular-table.js' and added the following code:

/mocks/angular-table.js

'use-strict'; angular.module('angular-table', []); 

I added this file to my karma.conf.js file, along with the real 'events' module I wanted to test:

karma.conf.js

... files = [     JASMINE,     JASMINE_ADAPTER,     'scripts/libs/angular.js',     'scripts/libs/angular-mocks.js',     'scripts/events.js', // this is the real module.     'scripts/mocks/*.js', //loads all custom mocks.     'scripts/specs/*.spec.js' // loads my spec file. ]  ... 

Finally in my spec file, I was able to add both modules by calling them separately in a beforeEach block:

specs/events.spec.js

beforeEach(function(){     module('angular-table');     module('events'); }); 

I got the idea to structure my files in this way from this post

like image 25
fscof Avatar answered Oct 15 '22 20:10

fscof