在Jest测试中,我一直得到“localStorage is not defined”,这是有意义的,但我的选项是什么?碰壁。
当前回答
在这里引用了一些其他的答案来解决一个用Typescript的项目。我像这样创建了一个LocalStorageMock:
export class LocalStorageMock {
private store = {}
clear() {
this.store = {}
}
getItem(key: string) {
return this.store[key] || null
}
setItem(key: string, value: string) {
this.store[key] = value
}
removeItem(key: string) {
delete this.store[key]
}
}
然后我创建了一个LocalStorageWrapper类,我使用它来访问应用程序中的所有本地存储,而不是直接访问全局本地存储变量。便于在包装器中为测试设置模拟。
其他回答
或者你只是像这样使用一个模拟包:
https://www.npmjs.com/package/jest-localstorage-mock
它不仅处理存储功能,还允许您测试是否实际调用了存储。
2022年12月:Nx 14使用Angular 14 Jest。 我们有一个测试设置。Ts文件在每个app和libs文件夹。我们设置本地存储模拟全局。
import 'jest-preset-angular/setup-jest';
Storage.prototype.getItem = jest.fn();
Storage.prototype.setItem = jest.fn();
Storage.prototype.removeItem = jest.fn();
然后localStorage.service.spec.ts文件如下所示:
import { LocalStorageService } from './localstorage.service';
describe('LocalStorageService', () => {
let localStorageService: LocalStorageService;
beforeEach(() => {
localStorageService = new LocalStorageService();
});
it('should set "identityKey" in localStorage', async () => {
localStorageService.saveData('identityKey', '99');
expect(window.localStorage.setItem).toHaveBeenCalled();
expect(window.localStorage.setItem).toHaveBeenCalledWith('identityKey', '99');
expect(window.localStorage.setItem).toHaveBeenCalledTimes(1);
});
it('should get "identityKey" from localStorage', async () => {
localStorageService.getData('identityKey');
expect(window.localStorage.getItem).toHaveBeenCalled();
expect(window.localStorage.getItem).toHaveBeenCalledWith('identityKey');
expect(window.localStorage.getItem).toHaveBeenCalledTimes(1);
});
it('should remove "identityKey" from localStorage', async () => {
localStorageService.removeData('identityKey');
expect(window.localStorage.removeItem).toHaveBeenCalled();
expect(window.localStorage.removeItem).toHaveBeenCalledWith('identityKey');
expect(window.localStorage.removeItem).toHaveBeenCalledTimes(1);
});
});
注:不好意思,这个SatckOverflow窗口很糟糕。
以下解决方案兼容更严格的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
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();
正如Niket Pathak在评论中提到的, 从jest@24 / jsdom@11.12.0及以上开始,localStorage将自动被模拟。
推荐文章
- 我如何使用Jest模拟JavaScript的“窗口”对象?
- 如何重置笑话模拟函数调用计数之前,每次测试
- 在单元测试中禁用控制台的更好方法
- 如何在单个测试基础上更改模拟实现?
- 如何处理玩笑测试中的localStorage ?
- 如何使用Jest测试对象键和值是否相等?
- 如何清除笑话缓存?
- 如何解决“不能在模块外使用导入语句”在开玩笑
- 如何使用Jest获得代码覆盖率报告?
- Console.log语句在Jest中不输出任何内容
- 测试过程。环境与玩笑
- 如何按顺序运行Jest测试?
- 如何在Jest中设置模拟约会?
- 如何使用jest和react-testing-library测试元素是否不存在?
- 如何使用ESLint与Jest