What I ultimately did was checked into the Angular source code for the $filter service (here) and found that it's pretty straightforward. It just uses the $injector service to find the registered filter by name and return it. So I mimicked that in my spy, except that I returned another spy when I came across the filter I wanted to test. It sounds a bit confusing (even to me) writing it out so why don't you just check out the code below. That should make more sense.
The code:
angular.module('app', []).factory('myFactory', function($filter) {
var factory = {};
factory.states = [
{ name: 'Alabama', id: 'AL' },
{ name: 'Alaskas', id: 'AK' },
{ name: 'Arizona', id: 'AZ' },
{ name: 'Arkansas', id: 'AR' }
];
factory.sort = function() {
return $filter('orderBy')(factory.states, 'id');
};
return factory;
});
The spec:
describe('test suite', function() {
var myFactory, orderByFilterSpy, filterSpy;
beforeEach(module('app'));
beforeEach(module(function($provide, $injector){
orderByFilterSpy = jasmine.createSpy('orderBy');
filterSpy = jasmine.createSpy('$filter').and.callFake(function(name) {
switch(name) {
case 'orderBy':
return orderByFilterSpy;
default:
return $injector.get(name + 'Filter');
}
});
$provide.factory('$filter', function() {
return filterSpy;
});
}));
beforeEach(inject(function(_myFactory_) {
myFactory = _myFactory_;
});
it('should call orderByFilter', function() {
// arrange
myFactory.states = [{id: 'AZ', name: 'Arizona'}, {id: 'AL', name: 'Alabama'}, {id: 'AK', name: 'Alaska'}, {id: 'AR', name: 'Arkansas'}];
// act
myFactory.sort();
// assert
expect(filterSpy).toHaveBeenCalledWith('orderBy');
expect(orderByFilterSpy).toHaveBeenCalledWith([{id: 'AZ', name: 'Arizona'}, {id: 'AL', name: 'Alabama'}, {id: 'AK', name: 'Alaska'}, {id: 'AR', name: 'Arkansas'}], 'id');
});
});
That's it! As a little added bonus, any filters other than orderBy that happen to get called in my factory should get passed through (I haven't validated that part yet, but it looks like it would do that so I'm rolling with it).
No comments:
Post a Comment