Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 362
David Bochenski Avatar asked Mar 08 '13 12:03

David Bochenski


1 Answers

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.

like image 180
David Bochenski Avatar answered Oct 23 '22 19:10

David Bochenski