在Jest测试中,我一直得到“localStorage is not defined”,这是有意义的,但我的选项是什么?碰壁。
当前回答
正如@ck4所建议的那样,文档已经清楚地解释了如何使用localStorage。然而,模拟函数无法执行任何localStorage方法。
下面是我的react组件的详细示例,它使用抽象方法来写入和读取数据,
//file: storage.js
const key = 'ABC';
export function readFromStore (){
return JSON.parse(localStorage.getItem(key));
}
export function saveToStore (value) {
localStorage.setItem(key, JSON.stringify(value));
}
export default { readFromStore, saveToStore };
错误:
TypeError: _setupLocalStorage2.default.setItem is not a function
解决办法: 为jest添加以下mock函数(路径:.jest/mocks/setUpStore.js)
let mockStorage = {};
module.exports = window.localStorage = {
setItem: (key, val) => Object.assign(mockStorage, {[key]: val}),
getItem: (key) => mockStorage[key],
clear: () => mockStorage = {}
};
Snippet从这里引用
其他回答
2021年,打印稿
class LocalStorageMock {
store: { [k: string]: string };
length: number;
constructor() {
this.store = {};
this.length = 0;
}
/**
* @see https://developer.mozilla.org/en-US/docs/Web/API/Storage/key
* @returns
*/
key = (idx: number): string => {
const values = Object.values(this.store);
return values[idx];
};
clear() {
this.store = {};
}
getItem(key: string) {
return this.store[key] || null;
}
setItem(key: string, value: string) {
this.store[key] = String(value);
}
removeItem(key: string) {
delete this.store[key];
}
}
export default LocalStorageMock;
然后你可以用它
global.localStorage = new LocalStorageMock();
不需要模拟localStorage—只需使用jsdom环境,这样您的测试就可以在类似浏览器的条件下运行。
在你的joke。config。js中,
module.exports = {
// ...
testEnvironment: "jsdom"
}
2022年的更新。
Jest@24+具有自动模拟本地存储的能力。但是,默认情况下,它不再附带所需的依赖项。
npm 和 -D 是 environment-jsdom
你还需要改变你的笑话测试模式:
// jest.config.cjs
module.exports = {
...
testEnvironment: "jsdom",
...
};
现在localStorage已经被模拟了。
例子:
// myStore.js
const saveLocally = (key, value) => {
localStorage.setItem(key, value)
};
测试:
// myStore.spec.ts
import { saveLocally } from "./myStore.js"
it("saves key-value pair", () => {
let key = "myKey";
let value = "myValue";
expect(localStorage.getItem(key)).toBe(null);
saveLocally(key, value);
expect(localStorage.getItem(key)).toBe(value);
};
这对我很有效,
delete global.localStorage;
global.localStorage = {
getItem: () =>
}
以下解决方案兼容更严格的TypeScript、ESLint、TSLint和Prettier配置测试:{"proseWrap": "always", "semi": false, "singleQuote": true, "trailingComma": "es5"}:
class LocalStorageMock {
public store: {
[key: string]: string
}
constructor() {
this.store = {}
}
public clear() {
this.store = {}
}
public getItem(key: string) {
return this.store[key] || undefined
}
public setItem(key: string, value: string) {
this.store[key] = value.toString()
}
public removeItem(key: string) {
delete this.store[key]
}
}
/* tslint:disable-next-line:no-any */
;(global as any).localStorage = new LocalStorageMock()
HT/ https://stackoverflow.com/a/51583401/101290了解如何更新global.localStorage