AngularJS inject service mock inside service tests

落爺英雄遲暮 提交于 2019-12-07 02:28:14

问题


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


回答1:


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.




回答2:


You could create a RootController and then inject it:

inject(function(myService, $controller){
  target = myService;
  $controller('rootController', {
        $scope : $rootScope.$new(),
        $rootScope : myService
  });
});  

With this approach you can access $rootScope functions from your 'myService'; Such 'myService.$on()'

I just made it, let me know if help is needed.



来源:https://stackoverflow.com/questions/16022320/angularjs-inject-service-mock-inside-service-tests

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!