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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With