Ho deciso di ribadire il mio commento alla risposta di Pumbaa80 come risposta separata in modo che sia più facile riutilizzarla come libreria.
Ho preso il codice di Pumbaa80, l'ho perfezionato un po ', ho aggiunto dei test e l'ho pubblicato come modulo npm qui:
https://www.npmjs.com/package/mock-local-storage .
Ecco un codice sorgente:
https://github.com/letsrock-today/mock-local-storage/blob/master/src/mock-localstorage.js
Alcuni test:
https://github.com/letsrock-today/mock-local-storage/blob/master/test/mock-localstorage.js
Il modulo crea finto localStorage e sessionStorage sull'oggetto globale (finestra o globale, quale di essi è definito).
Negli altri test del mio progetto l'ho richiesto con mocha come questo: mocha -r mock-local-storage
per rendere disponibili definizioni globali per tutto il codice sotto test.
Fondamentalmente, il codice ha il seguente aspetto:
(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));
Nota che tutti i metodi aggiunti tramite in Object.defineProperty
modo che non vengano iterati, acceduti o rimossi come elementi normali e non conteranno in lunghezza. Inoltre ho aggiunto un modo per registrare il callback che viene chiamato quando un elemento sta per essere inserito nell'oggetto. Questo callback può essere utilizzato per emulare l'errore di quota superata nei test.
Profit!