I have a fairly complex context that I wrap around my app to handle authentication and provide the associated data retrieved from the auth service. I'd like to bypass all of the functionality of the provider and just mock a return value. When the context renders, it performs a bunch of initialization functions that I don't want to happen when I test.
I tried something like this in my wrapper function:
const mockValue = {
error: null,
isAuthenticated: true,
currentUser: 'phony',
login: jest.fn(),
logout: jest.fn(),
getAccessToken: jest.fn(),
}
const MockAuthContext = () => ( React.createContext(mockValue) )
jest.mock("../contexts/AuthContext", () => ({
__esModule: true,
namedExport: jest.fn(),
default: jest.fn(),
}));
beforeAll(() => {
AuthContext.mockImplementation(MockAuthContext);
});
const customRender = (ui, { ...renderOpts } = {}) => {
const ProviderWrapper = ({ children }) => (
<AuthContext.Provider>
{children}
</AuthContext.Provider>
);
return render(ui, { wrapper: ProviderWrapper, ...renderOpts });
};
// re-export everything
export * from "@testing-library/react";
// override render method
export { customRender as render };
Alas, I get an error:
Error: Uncaught [Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
And, indeed, if I log what that Provider renders as, I get:
{
'$$typeof': Symbol(react.element),
type: undefined,
...
I've tried setting the provider to AuthContext.getMockImplementation().Provider. No dice.
Anyway, does anyone see what I'm trying to accomplish here? I'd like to just mock the entire context so that the component just gets a provider that returns known values without executing any context code. Is that possible with react-testing-library and Jest?
The error means that AuthContext.Provider
is not React component. AuthContext
is Jest spy, i.e. a function, and it doesn't have Provider
property. Since AuthContext
is expected to be React context, it should be defined as such. For default export it should be:
jest.mock("../contexts/AuthContext", () => ({
__esModule: true,
default: React.createContext()
}));
Then any mocked value can be provided in tests as:
<AuthContext.Provider value={mockValue}>