0

I am building an application using AngularJS and I am right now developing test cases for my application. Suppose I have a service like this;

var app = angular.module('MyApp')
app.factory('SessionService', function () {

    return {
        get: function (key) {
            return sessionStorage.getItem(key);
        },
        set: function (key, val) {
            return sessionStorage.setItem(key, val);
        },
        unset: function (key) {
            return sessionStorage.removeItem(key);
        }
    };
});

Can I write test case for my service like this;

beforeEach(module('MyApp'));
    describe('Testing Service : SessionService', function (SessionService) {
        var session, fetchedSession, removeSession, setSession;
        beforeEach(function () {
            SessionService = {
                get: function (key) {
                    return sessionStorage.getItem(key);
                },
                set: function (key, val) {
                    return sessionStorage.setItem(key, val);
                },
                unset: function (key) {
                    return sessionStorage.removeItem(key);
                }
            };
            spyOn(SessionService, 'get').andCallThrough();
            spyOn(SessionService, 'set').andCallThrough();
            spyOn(SessionService, 'unset').andCallThrough();
            setSession     = SessionService.set('authenticated', true);
            fetchedSession = SessionService.get('authenticated');
            removeSession  = SessionService.unset('authenticated');
        });
        describe('SessionService', function () {
            it('tracks that the spy was called', function () {
                expect(SessionService.get).toHaveBeenCalled();
            });
            it('tracks all the arguments used to call the get function', function () {
                expect(SessionService.get).toHaveBeenCalledWith('authenticated');
            });
            //Rest of the Test Cases
        });
    });

I am using Jasmine's spy method for developing this test case. Is it fine or am I wrong?

BKM
  • 6,949
  • 7
  • 30
  • 45
  • You can check below url: http://stackoverflow.com/questions/14773269/injecting-a-mock-into-an-angularjs-service – JQuery Guru Aug 02 '13 at 09:34

1 Answers1

1

It looks nice. But I think you will have some problems with this:

get: function (key) {
        return sessionStorage.getItem(key);
},

You're not mocking the sessionStorage. So i guess you will get an error when trying to call getItem() from this object. It seems that you're not interested in the return value of those calls in your tests. You only check if they were called with the correct attributes. Like here:

it('tracks that the spy was called', function () {
   expect(SessionService.get).toHaveBeenCalled();
});

Why don't you change your SessionService's mocks to return anything? Like this:

get: function (key) {
        return true;
},

If you want to test your getItem/setItem/removeItem you could do this in another test case

Felipe Skinner
  • 16,246
  • 2
  • 25
  • 30
  • So where I need to make change?. In the test case or in my service? – BKM Aug 05 '13 at 05:35
  • In the test case. Your service does what it needs to do. But your test case doesn't need to call all the methods within other methods. You can mock then to "true" or an empty string if your test doesn't depends on its return value (as it seems to be the case here) – Felipe Skinner Aug 05 '13 at 17:56