React Hook testing with renderHook

Viewed 7460

I want to test the state update of the component using renderHook from @testing-library/react-hooks, which let us render the hook in the same way as we do in a react functional component. Just want to know, is this only applicable for custom hooks, because the state is not getting changed when I am trying this for testing a component

it('test count update', () => {
    const { result } = renderHook(() => useState({ count: 0 }));
    const [state, setState] = result.current;
    const wrapper = mount(<ComponentToTest />);

    act(() => {
       wrapper.find('button').simulate('click');
    })
    expect(state).toBe({ count: 1 });
})

getting an error since the count is not getting updated and still remains 0

Can anyone please help

enter image description here

1 Answers

From the docs:

Renders a test component that will call the provided callback, including any hooks it calls, every time it renders.

renderHook is used to test the hook itself, not a component that uses that hook. renderHook itself renders a test component; you cannot test a hook's result by rendering a component that happens to use that hook.

In your case, you're just testing useState, which you can absolutely do with renderHook:

it('test count update', () => {
    const { result } = renderHook(() => useState({ count: 0 }));
    const [state, setState] = result.current;
    setState({count: state + 1});
    expect(state).toBe({ count: 1 });
})

But that seems kind of pointless; we know useState works.

If you want to test a component that uses useState (or any hook), you need to render the component itself and assert the result of that hook in the rendered component. E.g.

it('test count update', () => {
    const wrapper = mount(<ComponentToTest />);

    act(() => {
       wrapper.find('button').simulate('click');
    })
    // assuming the result is rendered in a span with a classname of 'result'
    expect(wrapper.find('span.result').text()).toBe('1');
})
Related