admin管理员组

文章数量:1279219

I have a simple angularjs filter (it takes an id and converts it to a name string), that depends on a custom service to do its work:

angular.module('app').filter('idToName',
  function(User) {
    return function(id) {
      var result, user;
      result = '';
      if (id) {
        result = 'no name found';
        user = User.getById(id);
        if (user) {
          result = user.firstName;
        }
      }
      return result;
    };
  }
);

and I want to write a unit test for it. I would like to be able to inject a mock of the User service into the test.

I can do this for a controller unit test as shown in the documentation:

var mockUserService;

mockUserService = {
  getById: function(id) {
    return {
      firstName: 'Bob'
    };
  }
};

beforeEach(inject(function($rootScope, $controller) {
  var ctrl, scope, userService;
  userService = mockUserService;
  scope = $rootScope.$new();
  return ctrl = $controller('someController', {
    $scope: scope,
    User: userService
  });
}));

but replacing $controller with $filter in the beforeEach does not work, as I presume filters are constructed differently by angular (i.e. don't allow you to inject locals as a second parameter to the constructor.)

Has anyone e across this / solved this before?

I have a simple angularjs filter (it takes an id and converts it to a name string), that depends on a custom service to do its work:

angular.module('app').filter('idToName',
  function(User) {
    return function(id) {
      var result, user;
      result = '';
      if (id) {
        result = 'no name found';
        user = User.getById(id);
        if (user) {
          result = user.firstName;
        }
      }
      return result;
    };
  }
);

and I want to write a unit test for it. I would like to be able to inject a mock of the User service into the test.

I can do this for a controller unit test as shown in the documentation:

var mockUserService;

mockUserService = {
  getById: function(id) {
    return {
      firstName: 'Bob'
    };
  }
};

beforeEach(inject(function($rootScope, $controller) {
  var ctrl, scope, userService;
  userService = mockUserService;
  scope = $rootScope.$new();
  return ctrl = $controller('someController', {
    $scope: scope,
    User: userService
  });
}));

but replacing $controller with $filter in the beforeEach does not work, as I presume filters are constructed differently by angular (i.e. don't allow you to inject locals as a second parameter to the constructor.)

Has anyone e across this / solved this before?

Share Improve this question edited Mar 8, 2013 at 13:01 CharlesB 90.5k29 gold badges201 silver badges228 bronze badges asked Mar 8, 2013 at 12:56 David BochenskiDavid Bochenski 3094 silver badges11 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 13

Ok, figured this out thanks largely to this answer.

The trick was to simply override the factory provider of the service, by using angular-mocks.js model function in a before each (angular just takes the last defined factory it would seem)

beforeEach(module(function($provide) {
  $provide.factory('User', function() {
    var getSync;
    getById = function(id) {
      return {
        firstName: 'Bob'
      };
    };
    return {
      getById: getById
    };
  });
}));

I suspect that I'll need to be careful with teardown between tests, but the injection into the filter now works fine.

本文标签: javascriptHow can i inject a mock service into a unit test for a filterStack Overflow