Dependencies and Unit Tests

Dependencies are one of the most widely used mechanisms in AngularJS. You see them everywhere, from dependency injection to global services. This can present a problem when it comes to unit tests because you don’t really want to have to test the full functionality of the dependency within the unit test. Instead, you will want to get the dependency and control it with your own mock objects and services.

There are four methods for controlling the dependency injection:

■ Create your own instance of the dependency using the new operator.

■ Create the dependency as a global object you can look up anywhere.

■ Ask a registry for it. This option requires that you have access to the registry as well, which means also placing it in a global location.

■ Have the dependency passed to you.

The following sections describe each of these methods in AngularJS.

Using the new Operator

Consider the following function and assume that MyService is a global service that you can create an instance of:

function MyClass() {
  this.doSomething = function() {
    var gSrv = new MyService();
    var data = sSrv.getSomething();
  }
}

To control MyService you would need to do something like this:

var savedMyService = MyService;
MyService = function MockMyService() {};
var myClass = new MyClass();
myClass.doSomething();
MyService = savedMyService;

This works; however, you run the risk of losing the handle to MyService if things go wrong, so you need to be careful.

Using a Global Lookup

This is similar to using the new operator. Consider the following function and assume that global.myService is a singleton instance of the MyService service you need:

function MyClass() {
  this.doSomething = function() {
    var data = global.myService.getSomething();
  }
}

To control MyService you would need to do something like this:

var savedMyService = global.myService;
global.myService = function MockMyService() {};
var myClass = new MyClass();
myClass.doSomething();
global.myService = savedMyService;

Again, this works, but because you run the risk of losing the handle to global.myService if things go wrong, you need to be careful.

Requesting the Dependency from a Registry

Consider the following function and assume that global.serviceRegistry is a singleton instance of a registry that has the MyService service registered:

function MyClass() {
  this.doSomething = function() {
    var myService = global.serviceRegistry.get('MyService'),
    var data = myService.getSomething();
  }
}

To control MyService you would need to do something like this:

var savedRegistry = global.serviceRegistry;
//create new globel.serviceRegistry
global.serviceRegistry.set('MyService', function MockMyService() {});
var myClass = new MyClass();
myClass.doSomething();
global.serviceRegistry = savedRegistry;

Again, this works, but because you run the risk of losing the handle to global.service-Registry if things go wrong, you need to be careful.

Passing the Dependency as a Parameter

I showed you the first three methods so that when you see the passed parameter method you will recognize that this is really the way you should be doing it. You should try to design your dependency usage such that the dependency can be passed in to the consumer. That way you can easily control the dependency from the test.

Now, consider the following function and assume that myService is an instance of a service that is typically passed in:

function MyClass() {
  this.doSomething = function(myService) {
    var data = myService.getSomething();
  }
}

To control MyService all you need to do is the following:

var mockedService = function MockMyService() {};
var myClass = new MyClass();
myClass.doSomething(mockedService);

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset