Skip to content

Instantly share code, notes, and snippets.

@jlozovei
Created October 27, 2023 14:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jlozovei/50e6db3a207f6d71cbab56481701707e to your computer and use it in GitHub Desktop.
Save jlozovei/50e6db3a207f6d71cbab56481701707e to your computer and use it in GitHub Desktop.
React + RTL context injection
// context/index.js
import { useReducer, useEffect, useMemo, createContext } from 'react';
import { reducer1, reducer2, reducer3 } from './reducers';
const Context = createContext({});
const STORAGE_KEY = 'my_awesome_storage'
const defaultState = {
user: {
name: null,
email: null
}
}
const combineReducers =
(...reducers) =>
(state, action) => {
for (let i = 0; i < reducers.length; i++) state = reducers[i](state, action);
return state;
};
const Provider = ({ injectedState = null, children }) => {
const [state, dispatch] = useReducer(
combineReducers(reducer1, reducer2, reducer3),
injectedState || defaultState
);
const contextValue = useMemo(() => {
return { state, dispatch };
}, [state, dispatch]);
useEffect(() => {
const stored = JSON.parse(localStorage.getItem(STORAGE_KEY));
if (stored) {
dispatch({
type: 'RETRIEVE_STORED_STATE',
payload: stored
});
}
}, []);
useEffect(() => {
if (state !== defaultState) {
localStorage.setItem(STORAGE_KEY, JSON.stringify(state));
}
}, [state]);
return <Context.Provider value={contextValue}>{children}</Context.Provider>;
};
export { Context, Provider };
// utils/customTestRender.js
import { Provider as ContextProvider, ToastProvider } from '@/context';
function Wrapper({ children, ...options }) {
return (
<ContextProvider injectedState={{ ...options?.context }}>
{children}
</ContextProvider>
);
}
const renderWithProviders = (ui, options = { wrapperProps: {} }) =>
render(ui, { wrapper: (props) => <Wrapper {...props} {...options?.wrapperProps} />, ...options });
export { renderWithProviders };
// some test file
import { screen } from '@testing-library/react';
import { SomeComponent } from '@/components';
import { renderWithProviders } from '@/utils/customTestRender';
describe('some test', () => {
it('Should test something', async () => {
const context = {
user: {
name: 'John Doe',
email: 'john@doe.com'
}
};
renderWithProviders(<SomeComponent />, { wrapperProps: { context } });
// your average expects here...
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment