David Bochenski
David Bochenski

Reputation: 309

How can i inject a mock service into a unit test for a filter?

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 come across this / solved this before?

Upvotes: 9

Views: 4028

Answers (1)

David Bochenski
David Bochenski

Reputation: 309

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.

Upvotes: 13

Related Questions