react-hooks-testing-library: Async callback was not invoked within the 5000ms timeout with waitForNextUpdate()
Helo! I could not solve the problem in 8 hours. Need help đ
Hook:
const useQuery = <T extends Object>(query: string, options: OptionsType = {}): ReturnType<T> => {
const initialState: InitialStateType<T> = { isFetching: false, data: null, errors: null }
const [ state, setState ] = useState(initialState)
const updatedOptions = useDeepMemo(() => ({
...options, query
}), [ options, query ])
const handleFetch = useCallback(() => {
const { variables, name = 'noName' } = updatedOptions
setState({ data: null, errors: null, isFetching: true })
return request.post(`graphql?name=${name}`, {
body: {
query,
variables,
},
})
.then(
(data: T) => {
console.log('RESOLVE ok') // Log for test
setState(() => ({ data, isFetching: false, errors: null, }))
},
({ errors }) => setState(() => ({ errors, isFetching: false, data: null })),
)
}, [ updatedOptions ])
useEffect(() => {
handleFetch()
}, [ updatedOptions ])
console.log('RENDER hook') // Log for test
return { ...state, fetch: handleFetch }
}
Test:
import { renderHook } from "@testing-library/react-hooks"
import useQuery from './useQuery'
jest.mock("sb-request", () => ({
post: jest.fn(async () => new Promise((r) => {
console.log('POST ok') // Log for test
setTimeout(() => r('success'), 1000)
})),
}))
describe("sb-hooks/useQuery", () => {
it("should return data after fetching", async () => {
const { result, waitForNextUpdate } = renderHook(() => useQuery('gql query', {
variables: {},
name: '1'
}))
await waitForNextUpdate();
expect(result.current.data).toEqual('success');
})
})
Console screen: https://prnt.sc/puclgu
â@testing-library/react-hooksâ: â2.0.3â, (and used 3.2.1) âreact-test-rendererâ: â16.8.6â, âreactâ: 16.8.6
No idea why waitForNextUpdate not see render(
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 19 (9 by maintainers)
Actually @JayantDaruvuri, I thought about this some more and the version of
react-dom
shouldnât affect your test (although it should match the others in a real app).I even confirmed my dependency suspicion by removing
react-dom
altogether and the test still passed after reloading the sandbox:Iâm not sure if you just needed to reload your sandbox (Iâve had issue when changing dependency versions) but the test passes for me with the same versions youâve got specified:
@mpeyper I managed to solve the issue, here is my solution:
My custom hook:
My new
preloadImages
util:My (finally) passing tests:
I ended up extracting the
new Image()
logic into its own util, that I can mock during tests.~It seems that this can happen with
^16.10.0
and"@testing-library/react-hooks": "^3.2.1",
~Update: turns out I was actually testing a default context that had no
value
set, so was hitting noops, so it seemed that my updates were not happening, but when I added mywrapper
that included the real implementation of the context, my updates were working correctly.Ok, so wasnât that bad to track down. I actually got my versions confused as to when we started requiring
react@6.19.0
as the minimum peer dependency.TL;DR; reverting
@testing-library/react-hooks
to^1.0.0
also passes the test, but with warnings about updates not wrapped inact
(what thereact@6.19.0
release enabled us to fix) -> https://codesandbox.io/s/zen-waterfall-blq6fThe longer version isnât much longer to be honest. In version
2.0.0
we wrappedwaitForNextUpdate
in the new asyncact
utility which allows you to await the promise and the updates get batched in the sameact
handler, removing the warning. Unfortunately, the previously supportedact(() => {})
calls also return a âpromise likeâ (presumably for debugging purposes if the name in the type definitions mean anything), which is what your tests ends up awaiting (Iâm not sure if it never resolves or how the promise like is intended to be used, but it definitely isnât waiting for your hook to rerender like you want it to.So your options are to roll react (and friends) forward to
^16.9.0
(recommended) or roll@testing-library/react-hooks
backwards to^1.0.0
and live with the hideous warning it produces (not recommended).