Я решил повторить свой комментарий к ответу Pumbaa80 как отдельный ответ, чтобы его было легче повторно использовать в качестве библиотеки.
Я взял код Pumbaa80, немного доработал его, добавил тесты и опубликовал его как модуль npm здесь:
https://www.npmjs.com/package/mock-local-storage .
Вот исходный код:
https://github.com/letsrock-today/mock-local-storage/blob/master/src/mock-localstorage.js
Некоторые тесты:
https://github.com/letsrock-today/mock-local-storage/blob/master/test/mock-localstorage.js
Модуль создает mock localStorage и sessionStorage на глобальном объекте (оконном или глобальном, какой из них определен).
В тестах другого моего проекта я требовал этого с мокко следующим образом: mocha -r mock-local-storage
сделать глобальные определения доступными для всего тестируемого кода.
В основном код выглядит следующим образом:
(function (glob) {
function createStorage() {
let s = {},
noopCallback = () => {},
_itemInsertionCallback = noopCallback;
Object.defineProperty(s, 'setItem', {
get: () => {
return (k, v) => {
k = k + '';
_itemInsertionCallback(s.length);
s[k] = v + '';
};
}
});
Object.defineProperty(s, 'getItem', {
// ...
});
Object.defineProperty(s, 'removeItem', {
// ...
});
Object.defineProperty(s, 'clear', {
// ...
});
Object.defineProperty(s, 'length', {
get: () => {
return Object.keys(s).length;
}
});
Object.defineProperty(s, "key", {
// ...
});
Object.defineProperty(s, 'itemInsertionCallback', {
get: () => {
return _itemInsertionCallback;
},
set: v => {
if (!v || typeof v != 'function') {
v = noopCallback;
}
_itemInsertionCallback = v;
}
});
return s;
}
glob.localStorage = createStorage();
glob.sessionStorage = createStorage();
}(typeof window !== 'undefined' ? window : global));
Обратите внимание, что все методы добавлены через, Object.defineProperty
поэтому они не будут повторяться, использоваться или удаляться как обычные элементы и не учитываются по длине. Также я добавил способ регистрации обратного вызова, который вызывается, когда элемент собирается быть помещенным в объект. Этот обратный вызов может использоваться для имитации ошибки превышения квоты в тестах.
Profit!