Reputation: 7911
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
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
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