Last active
November 6, 2021 07:21
-
-
Save ar-to/01fa07f2c03e7c1b2cfe6b8c612d4c6b to your computer and use it in GitHub Desktop.
Mock localStorage for jest
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Notes: | |
* - not showing component set up | |
* - not showing mock api setup | |
* - not showing initial state for redux | |
* - include react hooks and redux mocks | |
* @see https://stackoverflow.com/a/69847800/9270352 for more details on testing react hooks | |
* @see https://miragejs.com/quickstarts/react/test-a-component-with-react-testing-library/ for mock api library used here. Setup not shown here | |
*/ | |
import React from 'react' | |
import { MemoryRouter, Route } from 'react-router-dom' | |
import { render, screen } from '@testing-library/react' | |
import { Provider } from 'react-redux' | |
import { createStore, applyMiddleware, compose } from 'redux' | |
import createDebounce from 'redux-debounced' | |
import thunk from 'redux-thunk' | |
import createSagaMiddleware from 'redux-saga' | |
import rootReducer from 'redux/reducers/rootReducer' | |
import OperationPage from '../operation' | |
import { initialState } from '../mock' | |
import '@testing-library/jest-dom' // can be moved to a single setup file | |
import { runDemoServer } from '@demo/server' | |
import mockWindowProperty, { fakeLocalStorage } from '../mock-window-property' | |
const sagaMiddleware = createSagaMiddleware() | |
const middlewares = [thunk, sagaMiddleware, createDebounce()] | |
const composeEnhancers = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose | |
const store = createStore( | |
rootReducer, | |
// any type only until all reducers are given a type | |
initialState as any, | |
composeEnhancers(applyMiddleware(...middlewares)) | |
) | |
const Wrapper: React.FC = ({ children }) => <Provider store={store}>{children}</Provider> | |
mockWindowProperty('localStorage', fakeLocalStorage()) | |
describe('Operation Page - Local Storage', () => { | |
it('should work with local storage', async () => { | |
runDemoServer('test') | |
const testLS = { | |
id: 5, | |
name: 'My Test', | |
} | |
window.localStorage.setItem('currentPage', JSON.stringify(testLS)) | |
console.log('does it work?: ', window.localStorage.getItem('currentPage')) | |
const Element = () => ( | |
<MemoryRouter | |
initialEntries={[ | |
'/operations/integrations/trello?business=freelance&businessId=1&pageId=1&pageName=Trello', | |
]} | |
> | |
<Route path="/operations/:operation/:location"> | |
<OperationPage /> | |
</Route> | |
</MemoryRouter> | |
) | |
render(<Element />, { wrapper: Wrapper }) | |
const P = screen.getByRole('p') // assumes a p tag with the local storage value | |
screen.debug(P, 100000) | |
expect(window.localStorage.getItem('currentPage')).toEqual(JSON.stringify(testLS)) | |
expect(screen.getByText('My Test')).toBeInTheDocument() | |
}) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment