DEV Community

Ben Read
Ben Read

Posted on β€’ Edited on

4 1

How to test React hooks ... by not testing react hooks

React lifecycle methods are a pain to test. How do you know if your component mounted twice? How do you test for that? Why should you, since it's part of React's internal behaviour? Here's how we've started testing React hooks ... by not testing them at all!

Say I have my component written and it updates some messages from my API using a useEffect hook like this:

    useEffect(() => {
    if (data) {
        const messagesToUpdate = getAllMessagesToUpdate(data);
        messagesToUpdate &&
            messagesToUpdate.forEach(edge => {
                updateMessage({
                    variables: {
                        UpdateMessageInput: {
                            id: edge.node.id,
                            read: true,
                        },
                    },
                });
            });
    }
    }, [data, updateMessage]);
Enter fullscreen mode Exit fullscreen mode

How do I test each permutation of this call? I would need to mock the render cycle so that I can ensure that each time useEffect is called, this message does as it's expected.

Here's an alternative. Abstract the useEffect call into its own hook, and abstract the functionality into a separate function.

// in my main component
useUpdateMessages(data, updateMessage);

// in my hook
export function useUpdateMessages(data, updateMessage) {
   useEffect(() => {
        updateMessages(data, updateMessage);
    }, [data, updateMessage]);
}

// in my standalone function
export function updateMessages(data, updateMessage) {
    if (data) {
        const messagesToUpdate = getAllMessagesToUpdate(data);
        messagesToUpdate &&
            messagesToUpdate.forEach(edge => {
                updateMessage({
                    variables: {
                        UpdateMessageInput: {
                            id: edge.node.id,
                            read: true,
                        },
                    },
                });
            });
    }
}
Enter fullscreen mode Exit fullscreen mode

Now I don't need to worry about React lifecycle methods. I can test my hook if I want to, but it hardly seems worth it here. If I would, it would be easier to do so using react-hooks-testing-library

Additionally, I only need to worry about testing my standalone function, and that can be done much more easily now it's separated away from React's internal mechanism.

I like this approach a lot. Separate your code from the framework you're using. Even though there are more moving parts, it can facilitate much easier testing and a lot cleaner code.

Thanks to my colleague Stuart Nichols for this idea!

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

πŸ‘‹ Kindness is contagious

Please leave a ❀️ or a friendly comment on this post if you found it helpful!

Okay