Errors when using React Testing Library and renderHook to test hooks with multiple contexts
Asked Answered
C

0

8

Solved

Issue is tracked on github

I was attempting to test custom hooks using the react testing library, and the hook I was trying to put under test requires multiple context providers to work correctly. (authentication and notification)

The documentation here only outlines creating a wrapper with a single provider like so:

const wrapper = ({ children }) => <ContextProvider>{children}</ContextProvider>

However, my implementation needed something more complex, like so:

const wrapper = ({ children }) => (
    <ToastProvider>
        <NotificationProvider>
            <AuthProvider>{children}</AuthProvider>
        </NotificationProvider>
    </ToastProvider>
);

This was was failing at every attempt with the errors:

TypeError: parentInstance.children.indexOf is not a function

OR

Invariant Violation: Drop(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.

Leading me to believe there was no clear way to provide the right context without abandoning renderHook all together and building a test component that could fire off the necessary behaviors manually.

After a lot more digging I found this error buried in the logs:

Warning: An invalid container has been provided. This may indicate that another renderer is being used in addition to the test renderer. (For example, ReactDOM.createPortal inside of a ReactTestRenderer tree.) This is not supported.

Surely enough, it turns out there is a conflict with react-test-renderer and react-dom which causes calls to ReactDOM.createPortal to fail when under test. I assume this is somewhere in the ToastProvider, but the workaround is pretty simple.

Solved by adding this to the top of my test:

ReactDOM.createPortal = node => node
Cu answered 21/4, 2020 at 17:12 Comment(3)
If you're unit testing useAuth you only need to test that it returns the result of useContext(authContext) so if you'll mock useContext and createContext you can test that.Dogma
I ended up rewriting this to reflect the real issue I was having and to be informational only. It is fine to wrap renderHook with multiple contexts so long as the are no conflicting renderers, which can occur between react-dom and react-test-renderer.Cu
I wanted to mark #56258498 as a duplicate of this one as this has a much more elaborate desciption. Maybe you could rephrase it as a question and provide and accept your own answer? After that other similar questions can be linked to this one.Ode

© 2022 - 2024 — McMap. All rights reserved.