Reputation: 309
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
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