you shouldn't mock useSelector and useDispatch as eplained in the redux docs here: https://redux.js.org/usage/writing-tests… but you could control the intialstate pased in to store in your test or dispatch action in your test which should be more desirable… and this is how i implemented it following the docs.
in store/store.js
i created a function that returns a configure store function so i can pass in an initial state for the store
import { configureStore, combineReducers } from "@reduxjs/toolkit";
import { reducer } from "./yourSlice";
import { reducerTwo } from "./anotherSlice";
const rootReducer = combineReducers({
authState: reducer,
mode: reducerTwo
});
export default function setUpStore(preloadedState) {
return configureStore({ reducer: rootReducer, preloadedState });
}
in utils/RTKOveride.js
import { render } from "@testing-library/react";
import { Provider } from "react-redux";
import setUpStore from "store/store";
function renderWithWrapers(ui,
{
preloadedState = {},
store = setUpStore(preloadedState),
...options
} = {},
) {
function Wrapper({ children }) {
return (
<Provider store={store}>
{children}
</Provider>
);
}
return { store, ...render(ui, { wrapper: Wrapper, ...options }) };
}
export * from "@testing-library/react";
export { renderWithWrapers as render };
i overide the render function from RTK, wrapped my components that will be passed via the props.children in the provider component so components using useSelector and useDispatch still function properly.
even if you do not pass in a store or preloadedState(initialState) the code wont break as a store is created everytime the renderedWithWrapper is called
NOTE: the official react testing tookit explains how you could overide the render method and pass in additional options
then in your test/Component.test.js
import { render, screen } from "utils/RtkOveride";
import SomeComponent from "../Component";
test("some foo test", () => {
render(
<SomeComponent />
, { preloadedState: { authState: { state: true, refresh: "", access: "" } } }
);
const inputBar = screen.queryByText("foo", { exact: false });
expect(inputBar).toBeInTheDocument();
});
So you could pass in an initialState to change the default Slice InitialState or follow the other way the redux docs detailed...
Hopes this helps.