Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS inject service mock inside service tests

I have been trying to test a service to no avail for some time now and was hoping for some help. Here is my situation:

I have a service looking a little like this

myModule.factory('myService', ['$rootScope', '$routeParams', '$location', function($rootScope, $routeParams, $location) {

  var mySvc = {
    params: {}
  }

  // Listen to route changes.
  $rootScope.$on('$routeUpdate', mySvc.updateHandler);

  // Update @params when route changes
  mySvc.updateHandler = function(){ ... };

  ...
  ...

  return mySvc;

}]);

And I want to mock the services injected into 'myService' before the service gets injected into my tests so I can test the initialization code below

  var mySvc = {
    params: {}
  }

  // Listen to route changes.
  $rootScope.$on('$routeUpdate', mySvc.updateHandler);

I am using Jasmine for tests and mocks. This is what I came up with for now

describe('myService', function(){
  var rootScope, target;
  beforeEach(function(){
    rootScope = jasmine.createSpyObj('rootScope', ['$on']);

    module('myModule');
    angular.module('Mocks', []).service('$rootScope', rootScope );
    inject(function(myService){
      target = myService;
    });        
  });

  it('should be defined', function(){
    expect(target).toBeDefined();
  });

  it('should have an empty list of params', function(){
    expect(target.params).toEqual({});
  });

  it('should have called rootScope.$on', function(){
    expect(rootScope.$on).toHaveBeenCalled();
  });
});

This doesn't work though. My rootscope mock is not replacing the original and the Dependency Injection doc is confusing me more than anything.

Please help

like image 419
Abe Dadoun Avatar asked Apr 15 '13 18:04

Abe Dadoun


1 Answers

I would spy on the actual $rootScope instead of trying to inject your own custom object.

var target, rootScope;
beforeEach(inject(function($rootScope) {
  rootScope = $rootScope;

  // Mock everything here
  spyOn(rootScope, "$on")
}));

beforeEach(inject(function(myService) {
  target = myService;
}));

it('should have called rootScope.$on', function(){
  expect(rootScope.$on).toHaveBeenCalled();
});

I've tested this in CoffeScript, but the code above should still work.

like image 170
Guillaume Babin Avatar answered Oct 16 '22 05:10

Guillaume Babin