Mock an Angular Service

When we unit test an angular controller we test it in isolation replacing​ the services that the controller uses with test doubles (aka mocks). In Jasmine, the kind of test double used is called Spy​. (Read more:

The next code example shows the most basic beforeEach initialization block for a controller test suit. In it we use the $controller service to instantiate the controller under test MyCtrl injecting a new clean $scope before each test execution.

beforeEach(inject(function ($rootScope, $controller) {
    scope = $rootScope.$new();
    $controller('MyCtrl', {
        $scope: scope // inject the stubbed scope

During the instantiation of the controller, we can configure the mock services or stubbed data to inject. Notice that for all the dependencies that we don’t configure explicitly​ the unit test will use the real ones.
There are different ways to mock dependencies, I am going to show two alternatives here:

Replacing a service by a spy object

var stateSpy;
beforeEach(inject(function ($rootScope, $controller, MyService) {
    scope = $rootScope.$new();
    controller = $controller;
    stateSpy = jasmine.createSpyObj('$state', ['go']); // create a test double for a $state service with function called go
    $controller('MyCtrl', {
        $scope: scope,
        $state: stateSpy // inject the test double in the controller

Replacing the functions of a service by spies
Let’s say that MyCtrl makes use of a function getData() on a service called MyService. We can remplace that function with an spy and fake their response.

beforeEach(inject(function ($rootScope, $q, $controller, MyService) {
    scope = $rootScope.$new();
    q = $q;
    controller = $controller;
    spyOn(MyService, 'getData').and.callFake(function () {
        var deferred = $q.defer();
        return deferred.promise;
    $controller('MyCtrl', {
        $scope: scope

With this approach, we are replacing the functions of a service,​ not the service itself. If the function to spy doesn’t exist in the service the test will fail.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.