I'm writing tests for React using react-testing-library and jest and are having some problems figuring out how to set a preloadedState for my redux store, when another file imports the store.
I Have a function to set up my store like this
store.ts
export const history = createBrowserHistory()
export const makeStore = (initalState?: any) => configureStore({
reducer: createRootReducer(history),
preloadedState: initalState
})
export const store = makeStore()
and another js file like this
utils.ts
import store from 'state/store'
const userIsDefined = () => {
const state = store.getState()
if (state.user === undefined) return false
...
return true
}
I then have a test that looks something like this:
utils.test.tsx (the renderWithProvider is basically a render function that also wraps my component in a Render component, see: https://redux.js.org/recipes/writing-tests#connected-components)
describe("Test", () => {
it("Runs the function when user is defined", async () => {
const store = makeStore({ user: { id_token: '1' } })
const { container } = renderWithProvider(
<SomeComponent></SomeComponent>,
store
);
})
})
And the <SomeComponent> in turn calls the function in utils.ts
SomeComponent.tsx
const SomeComponent = () => {
if (userIsDefined() === false) return (<Forbidden/>)
...
}
Now.. What happens when the test is run seem to be like this.
- utils.ts is read and reads the line import store from 'state/store', this creates and saves a store variable where the user has not yet been defined.
- the utils.test.tsx is called and runs the code that calls const store = makeStore({ user: { id_token: '1' } }).
- The renderWithProvider() renderes SomeComponent which in turn calls the userIsDefined function.
- The if (state.user === undefined) returns false because state.user is still undefined, I think that's because utils.ts has imported the store as it were before I called my own makeStore({ user: { id_token: '1' } })?
The answer I want: I want to make sure that when call makeStore() again it updates the previously imported version of store that is being used in utils.ts. Is there a way to to this without having to use useSelector() and pass the user value from the component to my utils function?
e.g I could do something like this, but I'd rather not since I have a lot more of these files and functions, and rely much on import store from 'state/store':
SomeComponent.tsx
const SomeComponent = () => {
const user = useSelector((state: IState) => state.user)
if (userIsDefined(user) === false) return (<Forbidden/>)
...
}
utils.ts
//import store from 'state/store'
const userIsDefined = (user) => {
//const state = store.getState()
if (user === undefined) return false
...
return true
}
As I said above I'd prefer not to do it this way.
(btw I can't seem to create a fiddle for this as I don't know how to do that for tests and with this use case)
Thank you for any help or a push in the right direction.