tanmay
tanmay

Reputation: 7911

How to unit-test an AngularJS service that uses localStorage internally

How do I unit-test a factory that uses $window.localStorage internally using Jasmine and ngMock?

Here's something similar to what I have:

myApp.factory('myData',function ($window) {
    return { 
        message: $window.localStorage['stuff'] 
    }
});

Thanks a bunch!

Upvotes: 4

Views: 4953

Answers (2)

Dzmitry Atkayey
Dzmitry Atkayey

Reputation: 402

Small clarification: in case localStorage doesn't contain a key this mock return undefined, but real one returns null

The getItem(key) method must return the current value associated with the given key. If the given key does not exist in the list associated with the object then this method must return null. https://www.w3.org/TR/webstorage/

  spyOn(localStorage, 'getItem').and.callFake(function (key) {
    return store[key] !== undefined ? store[key] : null;
  });

Note: in the previous example method removeItem was not mocked

  spyOn(localStorage, 'removeItem').and.callFake(function (key, value) {
    delete store[key];
  });

P.S. I've found another way to write tests with local storage without mock it, probably it makes sense, working with primitives and localStorage could be tricky.

afterEach(() => {
  localStorage.removeItem(testTokenKey);
});

Upvotes: 3

andyhasit
andyhasit

Reputation: 15329

The following works with Jasmine 2.4:

angular.module('MyModule', []).factory('myData',function ($window) {
    return { 
        message: function(){
          return $window.localStorage['stuff'] ;
        }
    }
});

describe("TestName", function() {
  beforeEach(module('MyModule'));
  var myData, store;
  beforeEach(inject(function(_myData_) {
    myData = _myData_;
    store = {};
    var localStorage = window.localStorage;
    spyOn(localStorage, 'getItem').and.callFake(function (key) {
      return store[key];
    });
    spyOn(localStorage, 'setItem').and.callFake(function (key, value) {
      return store[key] = value + '';
    });
    spyOn(localStorage, 'clear').and.callFake(function () {
      store = {};
    });
  }));

  it("feature desc", function() {
    localStorage['stuff'] = 'hello';
    expect(myData.message()).toEqual('hello');
  });
});

Note use of the _myData_ underscore trick (see docs).

Upvotes: 6

Related Questions