Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock modules for angular testing

Lets say i have an angular module defined as

var app = angular.module('app',[dependenceny1Module,dependenceny2Module,dependenceny3Module......])

where app is a module which depends on bulk of other modules. Now for unit testing i can mock the module using

mock('app') 

but i have to create mock modules for all dependency modules like below

mockDependency1 = angular.module('dependency1Module')
mockDependency1 = angular.module('dependency2Module')

Or i have to load all the script files containing those modules.

I am wondering whats the best approach to mock out the dependency modules here? especially when dependency modules are too many.

like image 395
Rizwan Sharif Avatar asked Feb 12 '14 17:02

Rizwan Sharif


1 Answers

Look into requireJs to load your dependencies. With RequireJs, you can load different files for your production code and your test code.

Here is a (basic) example.

Let's say you have a javascript file with defines your angular module (named e.g app.js):

define(['dependency1Module', 'dependency2Module'], function(dependency1Module, dependency2Module) {
   var app = angular.module('app',['dependenceny1Module', 'dependenceny2Module']);
   return app;
}

Modules dependency1Module, dependency2Module, ... have a similar setup:

define(function() {
   var module = angular.module('dependenceny1Module');
   return module;
}

Now you need a bootstrap file (named e.g. bootstrap.js to define the location of the files. So you'll have two bootstrap files: one your your production code (using possible minified versions of some libraries) and a version for test purposes:

require.config({
  baseUrl: "path/to/production|test scripts",
  paths: {
    angular: 'path/to/angular',
    jquery: 'path/to/jquery',
  },
  shim: {
    angular: {
      exports: 'angular',
      deps: ['jquery']
    }
  }
});

require(["angular", "app", ], function(angular, app) {
  angular.element(document).ready(function() {
    angular.bootstrap(document, ['app']);
  });
});

Instead of changing the baseUrl, you could define different paths for the modules you want to mock:

paths: {
   dependency1Module: 'path/to.mock/dependency1Module'
}

Last step is to plugin the bootstrap file in your html code (production or test):

<script type="text/javascript" src="path/to/require.js"></script>
<script type="text/javascript" src="path/to/bootstrap(production|test).js"></script>

This is a basic requirejs setup. Of course, before you can use a certain angular type (e.g. controller, service, ...), you'll need to setup a requirejs module for it too (and requireit e.g in your app.js).

like image 189
asgoth Avatar answered Oct 03 '22 07:10

asgoth