Auto mock all localStorage and sessionStorage APIs for your Jest tests
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Jest LocalStorage Mock provides working localStorage and sessionStorage APIs for Jest tests. It auto-mocks both storage APIs with Jest spy functions, enabling comprehensive testing of web applications that rely on browser storage without requiring a browser environment.
npm install --save-dev jest-localstorage-mock or yarn add --dev jest-localstorage-mockSetup typically happens via Jest configuration (no explicit imports needed):
{
"jest": {
"resetMocks": false,
"setupFiles": ["jest-localstorage-mock"]
}
}Manual setup:
import "jest-localstorage-mock";
// or
require("jest-localstorage-mock");For create-react-app projects, add to src/setupTests.js:
require('jest-localstorage-mock');And override Jest config in package.json:
{
"jest": {
"resetMocks": false
}
}For direct LocalStorage class usage:
import { LocalStorage } from "jest-localstorage-mock/src/localstorage";// After setup, localStorage and sessionStorage are available globally
test('should save to localStorage', () => {
const KEY = 'foo', VALUE = 'bar';
// Use localStorage/sessionStorage normally
localStorage.setItem(KEY, VALUE);
// Test with Jest spies
expect(localStorage.setItem).toHaveBeenLastCalledWith(KEY, VALUE);
expect(localStorage.__STORE__[KEY]).toBe(VALUE);
expect(Object.keys(localStorage.__STORE__).length).toBe(1);
});
// Clear storage between tests
beforeEach(() => {
localStorage.clear();
jest.clearAllMocks();
});Core mock implementation that provides all localStorage/sessionStorage methods as Jest spy functions.
/**
* LocalStorage mock class with Jest spy functions
* @param {Object} jest - Jest instance for creating mock functions
*/
class LocalStorage {
constructor(jest);
/** Get item from storage (Jest spy) */
getItem(key: string): string | null;
/** Store item in storage (Jest spy) - values coerced to string */
setItem(key: string, val: any): void;
/** Remove item from storage (Jest spy) */
removeItem(key: string): void;
/** Clear all items from storage (Jest spy) */
clear(): void;
/** Get key at specified index (Jest spy) */
key(idx: number): string | null;
/** Return string representation '[object Storage]' (Jest spy) */
toString(): string;
/** Number of items in storage */
get length(): number;
/** Direct access to storage object for test assertions */
get __STORE__(): LocalStorage;
}All standard Web Storage API methods are provided as Jest spy functions.
/**
* Get item from storage
* @param {string} key - Storage key
* @returns {string|null} Stored value or null if not found
*/
getItem(key: string): string | null;
/**
* Store item in storage
* @param {string} key - Storage key
* @param {any} val - Value to store (coerced to string)
*/
setItem(key: string, val: any): void;
/**
* Remove item from storage
* @param {string} key - Storage key to remove
*/
removeItem(key: string): void;
/**
* Clear all items from storage
*/
clear(): void;
/**
* Get key name at specified index
* @param {number} idx - Index of key to retrieve
* @returns {string|null} Key name or null if index out of bounds
*/
key(idx: number): string | null;/**
* Number of items currently stored
*/
length: number;
/**
* Direct access to storage object for test assertions
* Backwards compatibility property
*/
__STORE__: LocalStorage;The setup file automatically creates mock instances on the global scope.
/**
* Global localStorage mock (automatically created)
*/
global.localStorage: LocalStorage;
/**
* Global sessionStorage mock (automatically created)
*/
global.sessionStorage: LocalStorage;
/**
* Alternative localStorage mock (non-writable, if _localStorage exists)
*/
global._localStorage?: LocalStorage;
/**
* Alternative sessionStorage mock (non-writable, if _sessionStorage exists)
*/
global._sessionStorage?: LocalStorage;test('localStorage operations', () => {
// Store data
localStorage.setItem('user', 'alice');
localStorage.setItem('theme', 'dark');
// Retrieve data
expect(localStorage.getItem('user')).toBe('alice');
expect(localStorage.getItem('missing')).toBeNull();
// Check storage state
expect(localStorage.length).toBe(2);
expect(localStorage.key(0)).toBe('user');
// Remove data
localStorage.removeItem('theme');
expect(localStorage.length).toBe(1);
// Clear all
localStorage.clear();
expect(localStorage.length).toBe(0);
});test('storage method calls', () => {
localStorage.setItem('key', 'value');
// Verify method was called
expect(localStorage.setItem).toHaveBeenCalledTimes(1);
expect(localStorage.setItem).toHaveBeenLastCalledWith('key', 'value');
// Verify method was not called
expect(localStorage.removeItem).not.toHaveBeenCalled();
});test('direct storage inspection', () => {
localStorage.setItem('item1', 'value1');
localStorage.setItem('item2', 'value2');
// Access storage object directly
expect(localStorage.__STORE__.item1).toBe('value1');
expect(localStorage.__STORE__.item2).toBe('value2');
// Check all stored keys
const keys = Object.keys(localStorage.__STORE__);
expect(keys).toEqual(['item1', 'item2']);
});test('value coercion to string', () => {
// All values are coerced to strings
localStorage.setItem('number', 42);
localStorage.setItem('boolean', true);
localStorage.setItem('object', { key: 'value' });
expect(localStorage.getItem('number')).toBe('42');
expect(localStorage.getItem('boolean')).toBe('true');
expect(localStorage.getItem('object')).toBe('[object Object]');
});test('storage object behavior', () => {
// toString returns proper representation
expect(localStorage.toString()).toBe('[object Storage]');
expect(localStorage.toString).toHaveBeenCalled();
// Verify key method behavior
localStorage.setItem('first', 'value1');
localStorage.setItem('second', 'value2');
expect(localStorage.key(0)).toMatch(/^(first|second)$/);
expect(localStorage.key(999)).toBeNull();
});describe('localStorage tests', () => {
beforeEach(() => {
// Clear storage data
localStorage.clear();
// Reset Jest mocks
jest.clearAllMocks();
// Or reset individual mocks:
// localStorage.setItem.mockClear();
});
test('clean state for each test', () => {
expect(localStorage.length).toBe(0);
expect(localStorage.setItem).toHaveBeenCalledTimes(0);
});
});