It is simply saying to use the same React context that the custom hook/component is using, not some other "random" auth provider.
Example Auth Context:
export const useAuth = () => useContext(AuthContext);
export const AuthProvider = ({ children }) => {
const [currentUser, setCurrentUser] = useState();
const [loading, setLoading] = useState(true);
const signup = (email, password) => {
return auth.createUserWithEmailAndPassword(email, password);
}
const login = (email, password) => {
return auth.signInWithEmailAndPassword(email, password);
}
const logout = () => auth.signOut();
...
const value = {
currentUser,
signup,
login,
logout,
};
return (
<AuthContext.Provider value={value}>
{children}
</AuthContext.Provider>
);
}
Example Consuming Component:
import { useAuth } from "../context/AuthContext"; // <-- specific context
export default function Dashboard() {
const { currentUser, logout } = useAuth(); // <-- specific context
...
return (
<div>
...
</div>
);
}
The specific AuthProvider component needs to appear above the component in the React tree in order to provide the Context and state.
If for example, like the unit test, you create another React Context provider:
const AuthContext2 = createContext(); // AuthContext2 to disambiguate it here
And wrap the component in a AuthContext2.Provider then the component is still importing and consuming the AuthProvider exported from code above.
The answer is saying to also import the AuthProvider and wrap that for the unit test instead of creating an entirely new Context.
import { AuthProvider } from "../context/AuthContext";
const AllTheProviders = ({ children }) => {
return (
<Router>
<AuthProvider>
{children}
</AuthProvider>
</Router>
);
};
const customRender = (ui, options) => {
render(ui, { wrapper: AllTheProviders, ...options });
};
Update
where would I feed in mock values?
Refactor the Context provider you have to consume an "initial state" prop that is used to set the initial state the context uses. Refactor the custom test renderer to take additional arguments and pass them through to wrappers.
@musicformellons
could you maybe make that refactor part of the answer...?!
Sure, should probably be included.
export const AuthProvider = ({ children, initialState }) => {
const [currentUser, setCurrentUser] = useState(initialState.currentUser);
...
const value = {
currentUser,
signup,
login,
logout,
};
return (
<AuthContext.Provider value={value}>
{children}
</AuthContext.Provider>
);
}
Test
import { AuthProvider } from "../context/AuthContext";
const AllTheProviders = ({ children }) => {
return (
<Router>
<AuthProvider initialState={authState}>
{children}
</AuthProvider>
</Router>
);
};
const customRender = (ui, options, initialState) => {
render(
ui,
{
wrapper: props => (
<AllTheProviders {...props} initialState={initialState} />
),
...options,
},
);
};