JSDom 11.12.0 - как издеваться над localStorage?
С момента последнего выпуска JSDom я не могу издеваться localStorage
больше.
Я пробовал следующие методы:
Object.defineProperty(window, 'localStorage', {value: LocalStorageMock})
window.localStorage = LocalStorageMock;
jest.spyOn(window.localStorage, 'setItem')
Любой из этих методов не работал для меня, я все время получаю оригинал localStorage
,
4 ответа
setItemSpy = jest.spyOn(Storage.prototype, 'setItem');
работает для меня.
Видел это исправление здесь: https://github.com/facebook/jest/issues/6858
Вы можете использовать пакет dom-storage, доступный через npm:
const Storage = require('dom-storage');
global.localStorage = new Storage(null, { strict: true });
global.sessionStorage = new Storage(null, { strict: true });
Мы используем последнюю версию jsdom
для наших модульных тестов и вышеупомянутый метод работал отлично.
Я действительно столкнулся с этой же проблемой при обновлении Jest, но не уверен, что это случилось с вами, но я нашел это исправление здесь: https://github.com/facebook/jest/issues/6766
От OlivierB-OB:
В качестве временного решения вы можете установить jsdom "11.11.0" (точный) в качестве dev-зависимости в вашем пакете. Затем jest-environment-jsdom должен использовать эту версию вместо последней версии 11.12.0, вызывающей такое поведение. Ура!
После этого я проверял местное хранилище в настройках теста, и шпионаж возвращался к норме.
И реализация макета localstorage: https://github.com/facebook/jest/issues/2098 однако, не содержит removeItem, поэтому вам, возможно, придется добавить его.
Я создал функцию, которая издевается над
localStorage
. Он реализует только два метода
getItem
а также
setItem
. При необходимости вы можете легко добавить другие методы.
export const localStorageImpl = {
register: () => {
let storage = (window as any).customLocalStorage;
if(storage) {
return {
storage,
methods: (window as any).customLocalStorageMethods
}
}
storage = (window as any).customLocalStorage = {} as any;
const setItem = jest.spyOn(Storage.prototype, 'setItem');
setItem.mockImplementation((key, value) => {
storage[key] = value;
});
const getItem = jest.spyOn(Storage.prototype, 'getItem');
getItem.mockImplementation((key) => {
return storage[key];
});
const methods = (window as any).customLocalStorageMethods = {
setItem,
getItem
};
return {
storage,
methods
}
},
unregister: () => {
const methods = (window as any).customLocalStorageMethods;
if(methods){
const { setItem, getItem } = methods as { setItem: jest.SpyInstance<void, [key: string, value: string]>, getItem: jest.SpyInstance<string, [key: string]> };
setItem.mockReset();
getItem.mockReset();
}
delete (window as any).customLocalStorageMethods;
delete (window as any).customLocalStorage;
}
}
Применение:
it('should mock localStorage', () => {
const { methods } = localStorageImpl.register(); // mock localStorage
const { getByTestId } = render(<Root />);
fireEvent.click(getByTestId('column-size'));
expect(methods.setItem).toBeCalledTimes(1);
localStorageImpl.unregister();
});