localstorage getitem ejemplos jestjs

jestjs - getitem - localstorage json



¿Cómo trato con localStorage en las pruebas de broma? (12)

Actualmente (enero ''19) localStorage no puede ser burlado o espiado por broma como lo haría normalmente, y como se describe en los documentos de crear-reaccionar-aplicación. Esto se debe a los cambios realizados en jsdom. Puede leer sobre esto aquí https://github.com/facebook/jest/issues/6798 y aquí https://github.com/jsdom/jsdom/issues/2318 .

Como solución alternativa, puede espiar el prototipo en su lugar:

// does not work: jest.spyOn(localStorage, "setItem"); localStorage.setItem = jest.fn(); // works: jest.spyOn(window.localStorage.__proto__, ''setItem''); window.localStorage.__proto__.setItem = jest.fn(); // assertions as usual: expect(localStorage.setItem).toHaveBeenCalled();

Sigo recibiendo "localStorage no está definido" en las pruebas de Jest, lo que tiene sentido, pero ¿cuáles son mis opciones? Golpear paredes de ladrillo.


Como @ ck4 la documentation sugerida tiene una explicación clara para usar localStorage en broma. Sin embargo, las funciones simuladas no pudieron ejecutar ninguno de los métodos localStorage .

A continuación se muestra el ejemplo detallado de mi componente de reacción que utiliza métodos abstractos para escribir y leer datos,

//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 };

Error:

TypeError: _setupLocalStorage2.default.setItem is not a function

Reparar:
Agregue la siguiente función simulada para jest (ruta: .jest/mocks/setUpStore.js )

let mockStorage = {}; module.exports = window.localStorage = { setItem: (key, val) => Object.assign(mockStorage, {[key]: val}), getItem: (key) => mockStorage[key], clear: () => mockStorage = {} };

Se hace referencia al fragmento desde here


Encontré esta solución de github

describe(''getToken'', () => { const Auth = new AuthService(); const token = ''eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Ik1yIEpvc2VwaCIsImlkIjoiNWQwYjk1Mzg2NTVhOTQ0ZjA0NjE5ZTA5IiwiZW1haWwiOiJ0cmV2X2pvc0Bob3RtYWlsLmNvbSIsInByb2ZpbGVVc2VybmFtZSI6Ii9tcmpvc2VwaCIsInByb2ZpbGVJbWFnZSI6Ii9Eb3Nlbi10LUdpci1sb29rLWN1dGUtbnVrZWNhdDMxNnMtMzExNzAwNDYtMTI4MC04MDAuanBnIiwiaWF0IjoxNTYyMzE4NDA0LCJleHAiOjE1OTM4NzYwMDR9.YwU15SqHMh1nO51eSa0YsOK-YLlaCx6ijceOKhZfQZc''; beforeEach(() => { global.localStorage = jest.fn().mockImplementation(() => { return { getItem: jest.fn().mockReturnValue(token) } }); }); it(''should get the token from localStorage'', () => { const result = Auth.getToken(); expect(result).toEqual(token); }); });

Puede insertar este código en sus SetupTests y debería funcionar bien.

Lo probé en un proyecto con typectipt.


Gran solución de

Sin embargo, usamos la sintaxis ES2015 y sentí que era un poco más limpio escribirlo de esta manera.

class LocalStorageMock { constructor() { this.store = {}; } clear() { this.store = {}; } getItem(key) { return this.store[key] || null; } setItem(key, value) { this.store[key] = value.toString(); } removeItem(key) { delete this.store[key]; } }; global.localStorage = new LocalStorageMock;


La siguiente solución es compatible para pruebas con TypeScript, ESLint, TSLint y Prettier config más estrictos: { "proseWrap": "always", "semi": false, "singleQuote": true, "trailingComma": "es5" } :

var localStorageMock = (function() { var store = {}; return { getItem: function(key) { return store[key] || null; }, setItem: function(key, value) { store[key] = value.toString(); }, clear: function() { store = {}; } }; })(); Object.defineProperty(window, ''localStorage'', { value: localStorageMock });

HT / https://.com/a/51583401/101290 sobre cómo actualizar global.localStorage


Lo descubrí con la ayuda de esto: https://groups.google.com/forum/#!topic/jestjs/9EPhuNWVYTg

Configure un archivo con los siguientes contenidos:

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 });

Luego agrega la siguiente línea a su package.json bajo sus configuraciones de Jest

"setupTestFrameworkScriptFile":"PATH_TO_YOUR_FILE",


Riffed algunas otras respuestas aquí para resolverlo para un proyecto con Typecript. Creé un LocalStorageMock como este:

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] } }

Luego creé una clase LocalStorageWrapper que uso para todo el acceso al almacenamiento local en la aplicación en lugar de acceder directamente a la variable de almacenamiento local global. Facilitó la configuración del simulacro en el contenedor para las pruebas.


Si está buscando un simulacro y no un trozo, aquí está la solución que uso:

export const localStorageMock = { getItem: jest.fn().mockImplementation(key => localStorageItems[key]), setItem: jest.fn().mockImplementation((key, value) => { localStorageItems[key] = value; }), clear: jest.fn().mockImplementation(() => { localStorageItems = {}; }), removeItem: jest.fn().mockImplementation((key) => { localStorageItems[key] = undefined; }), }; export let localStorageItems = {}; // eslint-disable-line import/no-mutable-exports

Exporto los elementos de almacenamiento para una fácil inicialización. IE puedo configurarlo fácilmente en un objeto

En las versiones más recientes de Jest + JSDom no es posible configurar esto, pero el almacenamiento local ya está disponible y puede espiarlo de esta manera:

const setItemSpy = jest.spyOn(Object.getPrototypeOf(window.localStorage), ''setItem'');


Si usa create-react-app, hay una solución más simple y directa explicada en la documentation .

Crea src/setupTests.js y pon esto en él:

const localStorageMock = { getItem: jest.fn(), setItem: jest.fn(), clear: jest.fn() }; global.localStorage = localStorageMock;

Contribución de Tom Mertz en un comentario a continuación:

Luego puede probar que las funciones de su localStorageMock se usan haciendo algo como

expect(localStorage.getItem).toBeCalledWith(''token'') // or expect(localStorage.getItem.mock.calls.length).toBe(1)

dentro de sus pruebas si quería asegurarse de que se llamara. Echa un vistazo a https://facebook.github.io/jest/docs/en/mock-functions.html


Una mejor alternativa que maneja valores undefined (no tiene toString() ) y devuelve null si el valor no existe. Probado esto con react v15, redux y redux-auth-wrapper

class LocalStorageMock { constructor() { this.store = {} } clear() { this.store = {} } getItem(key) { return this.store[key] || null } setItem(key, value) { this.store[key] = value } removeItem(key) { delete this.store[key] } } global.localStorage = new LocalStorageMock



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()

Cree un simulacro y agréguelo al objeto global