Skip to content

Instantly share code, notes, and snippets.

@zhenyi2697
Created July 8, 2015 20:11
Show Gist options
  • Save zhenyi2697/bd0efe0a315f6d17517c to your computer and use it in GitHub Desktop.
Save zhenyi2697/bd0efe0a315f6d17517c to your computer and use it in GitHub Desktop.
JavaScript: Test localStorage
'use strict'
// The helper
(function(self) {
//helper guts goes here :)
//data store for holding objects
var localStore = {};
//localStorage mock for interacting with localStore
var fakeLocalStorage = {
getItem: function (key) {
return localStore[key];
},
setItem: function (key, value) {
localStore[key] = val+'';
},
removeItem: function (key) {
delete localStore[key];
},
clear: function() {
localStore = {};
}
}
// Helper function
function setupMockLocalStorage(windowObject) {
//first, check to see if the browser is phantom
if(windowObject.navigator && windowObject.navigator.userAgent.match(/Phantom/g)) {
//localStorage object being read-only, we have to spy and redirect function calls...
spyOn(windowObject.localStorage, 'getItem')
.andCallFake(fakeLocalStorage.getItem);
spyOn(windowObject.localStorage, 'setItem')
.andCallFake(fakeLocalStorage.setItem);
spyOn(windowObject.localStorage, 'removeItem')
.andCallFake(fakeLocalStorage.removeItem);
spyOn(windowObject.localStorage, 'clear')
.andCallFake(fakeLocalStorage.clear);
} else {
//Anything other than Phantom, we can just replace the definition for windowObject.localStorage with our own custom one
Object.defineProperty(windowObject, 'localStorage', {value: fakeLocalStorage, writable: true});
//Create our spies so we can tell when functions were called, etc...
//using .andCallThrough() tells the spy to allow the function to go ahead and get called rather than redirecting to another function
spyOn(windowObject.localStorage, 'getItem')
.andCallThrough();
spyOn(windowObject.localStorage, 'setItem')
.andCallThrough();
spyOn(windowObject.localStorage, 'removeItem')
.andCallThrough();
spyOn(windowObject.localStorage, 'clear')
.andCallThrough();
}
}
//here's the object that actually gets exposed to be used by test fixtures
self.localStorageMockSpy = {
setup: setupMockLocalStorage
};
//if module.exports, then this should work with require() if needed - I've not tested this yet though :)
}((module||{}).exports || window));
// The actual test
describe('SessionService', function() {
var sessionService, $window;
var keyToTest = 'testItem';
var dataToTest = {data: 'test data'}
beforeEach(function(){
module('atlas-gui');
//inject our dependencies.
//instead of using $window, use _$window_ so that you can have your local reference named $window. It will pull in the appropriate item.
inject(function (_$window_, _sessionService_) {
$window = _$window_;
sessionService = _sessionService_;
});
//now that our $window object is populated, set up the mock and spies for its localStorage property:
window.localStorageMockSpy.setup($window);
window.localStorage.setItem(keyToTest, dataToTest);
});
afterEach(function(){
localStorageWidgetService.clear();
});
it('should retrieve a data from session', function() {
var data = sessionService.get(keyToTest);
expect(data).toEqual(dataToTest);
expect(window.localStorage.getItem).toHaveBeenCalledWith(keyToTest);
});
// More test goes here ...
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment