在Jest测试中,我一直得到“localStorage is not defined”,这是有意义的,但我的选项是什么?碰壁。
当前回答
在这个网站的帮助下,我们找到了答案:https://groups.google.com/forum/#!主题/ jestjs / 9 ephunwvytg
设置一个包含以下内容的文件:
var localStorageMock = (function() {
var store = {};
return {
getItem: function(key) {
return store[key];
},
setItem: function(key, value) {
store[key] = value.toString();
},
clear: function() {
store = {};
},
removeItem: function(key) {
delete store[key];
}
};
})();
Object.defineProperty(window, 'localStorage', { value: localStorageMock });
然后将以下行添加到包中。json在你的Jest配置
:“setupTestFrameworkScriptFile PATH_TO_YOUR_FILE”,
其他回答
上面的答案对我都没用。经过一番挖掘,这就是我要做的。这要归功于一些来源和其他答案。
https://www.codeblocq.com/2021/01/Jest-Mock-Local-Storage/ https://github.com/facebook/jest/issues/6798#issuecomment-440988627 https://gist.github.com/mayank23/7b994385eb030f1efb7075c4f1f6ac4c https://github.com/facebook/jest/issues/6798#issuecomment-514266034
我的全部要点:https://gist.github.com/ar-to/01fa07f2c03e7c1b2cfe6b8c612d4c6b
/**
* Build Local Storage object
* @see https://www.codeblocq.com/2021/01/Jest-Mock-Local-Storage/ for source
* @see https://stackoverflow.com/a/32911774/9270352 for source
* @returns
*/
export const fakeLocalStorage = () => {
let store: { [key: string]: string } = {}
return {
getItem: function (key: string) {
return store[key] || null
},
setItem: function (key: string, value: string) {
store[key] = value.toString()
},
removeItem: function (key: string) {
delete store[key]
},
clear: function () {
store = {}
},
}
}
/**
* Mock window properties for testing
* @see https://gist.github.com/mayank23/7b994385eb030f1efb7075c4f1f6ac4c for source
* @see https://github.com/facebook/jest/issues/6798#issuecomment-514266034 for sample implementation
* @see https://developer.mozilla.org/en-US/docs/Web/API/Window#properties for window properties
* @param { string } property window property string but set to any due to some warnings
* @param { Object } value for property
*
* @example
*
* const testLS = {
* id: 5,
* name: 'My Test',
* }
* mockWindowProperty('localStorage', fakeLocalStorage())
* window.localStorage.setItem('currentPage', JSON.stringify(testLS))
*
*/
const mockWindowProperty = (property: string | any, value: any) => {
const { [property]: originalProperty } = window
delete window[property]
beforeAll(() => {
Object.defineProperty(window, property, {
configurable: true,
writable: true,
value,
})
})
afterAll(() => {
window[property] = originalProperty
})
}
export default mockWindowProperty
不幸的是,我在这里找到的解决方案对我不起作用。
所以我在看Jest GitHub的问题,发现了这个帖子
得到最多好评的解决方案是:
const spy = jest.spyOn(Storage.prototype, 'setItem');
// or
Storage.prototype.getItem = jest.fn(() => 'bla');
答:
目前(7月22日)localStorage不能像你通常会被嘲笑或监视,并在创建-反应-应用程序文档中概述。这是由于jsdom中所做的更改。你可以在jest和jsdom问题跟踪器中读到它。
作为一种变通方法,你可以监视原型:
// does not work:
jest.spyOn(localStorage, "setItem");
localStorage.setItem = jest.fn();
// either of these lines will work, different syntax that does the same thing:
jest.spyOn(Storage.prototype, 'setItem');
Storage.prototype.setItem = jest.fn();
// assertions as usual:
expect(localStorage.setItem).toHaveBeenCalled();
关于监视原型机的注意事项:
监视实例使您能够观察和模拟特定对象的行为。
另一方面,监视原型,将同时观察/操作该类的每个实例。除非您有一个特殊的用例,否则这可能不是您想要的。
但是,在本例中没有区别,因为localStorage只存在一个实例。
首先,我创建了一个名为localStorage.ts(localStorage.js)的文件
class LocalStorageMock {
store: Store;
length: number;
constructor() {
this.store = {};
this.length = 0;
}
key(n: number): any {
if (typeof n === 'undefined') {
throw new Error(
"Uncaught TypeError: Failed to execute 'key' on 'Storage': 1 argument required, but only 0 present."
);
}
if (n >= Object.keys(this.store).length) {
return null;
}
return Object.keys(this.store)[n];
}
getItem(key: string): Store | null {
if (!Object.keys(this.store).includes(key)) {
return null;
}
return this.store[key];
}
setItem(key: string, value: any): undefined {
if (typeof key === 'undefined' && typeof value === 'undefined') {
throw new Error(
"Uncaught TypeError: Failed to execute 'setItem' on 'Storage': 2 arguments required, but only 0 present."
);
}
if (typeof value === 'undefined') {
throw new Error(
"Uncaught TypeError: Failed to execute 'setItem' on 'Storage': 2 arguments required, but only 1 present."
);
}
if (!key) return undefined;
this.store[key] = value.toString() || '';
this.length = Object.keys(this.store).length;
return undefined;
}
removeItem(key: string): undefined {
if (typeof key === 'undefined') {
throw new Error(
"Uncaught TypeError: Failed to execute 'removeItem' on 'Storage': 1 argument required, but only 0 present."
);
}
delete this.store[key];
this.length = Object.keys(this.store).length;
return undefined;
}
clear(): undefined {
this.store = {};
this.length = 0;
return undefined;
}
}
export const getLocalStorageMock = (): any => {
return new LocalStorageMock();
};
global.localStorage = new LocalStorageMock();
然后创建名为session.test.ts的测试文件(session.test.js)
import { getLocalStorageMock } from '../localstorage';
describe('session storage', () => {
let localStorage;
beforeEach(() => {
localStorage = getLocalStorageMock();
});
describe('getItem', () => {
it('should return null if the item is undefined', () => {
expect(localStorage.getItem('item')).toBeNull();
});
it("should return '' instead of null", () => {
localStorage.setItem('item', '');
expect(localStorage.getItem('item')).toBe('');
});
it('should return navid', () => {
localStorage.setItem('item', 'navid');
expect(localStorage.getItem('item')).toBe('navid');
});
});
});
在这个网站的帮助下,我们找到了答案:https://groups.google.com/forum/#!主题/ jestjs / 9 ephunwvytg
设置一个包含以下内容的文件:
var localStorageMock = (function() {
var store = {};
return {
getItem: function(key) {
return store[key];
},
setItem: function(key, value) {
store[key] = value.toString();
},
clear: function() {
store = {};
},
removeItem: function(key) {
delete store[key];
}
};
})();
Object.defineProperty(window, 'localStorage', { value: localStorageMock });
然后将以下行添加到包中。json在你的Jest配置
:“setupTestFrameworkScriptFile PATH_TO_YOUR_FILE”,
推荐文章
- 我如何使用Jest模拟JavaScript的“窗口”对象?
- 如何重置笑话模拟函数调用计数之前,每次测试
- 在单元测试中禁用控制台的更好方法
- 如何在单个测试基础上更改模拟实现?
- 如何处理玩笑测试中的localStorage ?
- 如何使用Jest测试对象键和值是否相等?
- 如何清除笑话缓存?
- 如何解决“不能在模块外使用导入语句”在开玩笑
- 如何使用Jest获得代码覆盖率报告?
- Console.log语句在Jest中不输出任何内容
- 测试过程。环境与玩笑
- 如何按顺序运行Jest测试?
- 如何在Jest中设置模拟约会?
- 如何使用jest和react-testing-library测试元素是否不存在?
- 如何使用ESLint与Jest