我决定重申我对 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
模块在全局对象(窗口或全局,它们中的哪一个被定义)上创建模拟 localStorage 和 sessionStorage。
在我的另一个项目的测试中,我要求它与 mocha 一样: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
,以便它们不会作为常规项目被迭代、访问或删除,并且不会计入长度。我还添加了一种注册回调的方法,当一个项目即将被放入对象时调用它。此回调可用于模拟测试中超出配额的错误。