Search code examples
unit-testingangularjsjasmineangularjs-service

Testing a AngularJS services with dependencies


I have som issues testing a simple service in AngularJS, which depends on another service.

The service looks a bit like this:

serviceModule.factory('filtersService', ['$rootScope', 'urlService', function($rootScope, urlService){
        return {
            getFilters: function(){
                   if(urlService.getPathName() == "test")
                   {
                      return "something";
               }
    }]);

In the start I just tried to use window.location.pathname instead of creating a service, but it seemed like the wrong way to be able to mock it. I therefore created the urlService, which is basically a simple wrapper around the window-object.

I then have my filtersServiceTest which looks like this:

describe('filtersService test', function(){
    var filtersService, urlServiceMock;

    beforeEach(module('App.services'));

    beforeEach(function(){
        urlServiceMock = {
            getPathName: function(){
                return "";
            }
        };

        module(function($provide){
            $provide.value('urlService', urlServiceMock);
        });
    });

    it('Should return something if url is test', inject(function(filtersService){
        urlServiceMock = {
            getPathName: function(){
                return "test";
            }
        };

        expect(filtersService.getFilters()).not.toBe("something");
    }));
});

But this doesn't seem to work. I can't overload the urlServiceMock before it is actually run. I could change the 'beforeEach' each so getPathName returns "test", but then I would not be able to test scenarious where the urls isn't equal to test.


Solution

  • You can spy on a service in your test suite to change the behavior:

    spyOn(yourService, 'methodName');
    

    There is a great example on jsFiddle on how to implement a spy: http://jsfiddle.net/robinroestenburg/aDwva/

    That should allow you get it working correctly.