testing-library / react-hooks-testing-library

🐏 Simple and complete React hooks testing utilities that encourage good testing practices.
https://react-hooks-testing-library.com
MIT License
5.25k stars 233 forks source link

Async update to `useReducer` does not trigger callback #273

Closed bolivier closed 4 years ago

bolivier commented 4 years ago

Relevant code or config:

useFoo.js

const reducer = (state, val) =>  val;

export function useFoo() {
    const [state, dispatch] = useReducer(reducer);

    useEffect(() => {
        dispatch('hello world');
    }, []);

    return [state];
}

useFoo.test.js

test("simple test", async () => {
    const { result, waitForNextUpdate } = renderHook(() => useFoo());

    await waitForNextUpdate();

    expect(result.current[0]).toEqual("hello world");
});

What you did:

I'm trying to test a hook that uses useReducer and updates asynchronously (my real use case is using a mocked api, but useEffect produces the same behavior).

What happened:

I expect that the test should pass, because the update fn is called, but it times out with the message

Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.Error:

Reproduction:

I have a codesandbox with the relevant code here and I also have a github repo here

Problem description:

Suggested solution:

mpeyper commented 4 years ago

I'm about to go on holiday for a week, so apologies if I'm a bit on and off checking back here.

The sandbox seems to be missing a few things to work (react-test-renderer dependency and the hook itself), and I'm on my phone so modifying it myself is tough, so as a guess, try removing the awaitwaitForNextUpdate() and see what ii says. I'm pretty sure the first effect will occur before renderHook exits

bolivier commented 4 years ago

Codesandbox got mixed up and didn't save my changes. That example is working fine. I'm going to close without a reproducible error.