react-native-testing-library: `renderHook` result values with `waitFor` not working
Describe the bug
Using the new renderHook
function included in this library does not behave the same way when it comes to awaiting different return values as the other implementations (referencing specifically react-hooks
+ testing-library/react
).
Trying to waitFor
different values to change from the hook directly does not seem to be functioning as expected.
Expected behavior
If https://github.com/testing-library/react-hooks-testing-library is going to be deprecated in favor of this library, I’d expect to retain the same functionality the previous library offered since it was created to test complex hooks without the need for testing the components using these hooks as well. I’d also expect similar functionality to the testing-library/react
implementation.
waitFor
should be able to handle waiting for the values of the hook to match the expectation passed to it
Steps to Reproduce
Consider the following hook:
const useCount = () => {
const [count, setCount] = useState(0)
useEffect(() => {
const retrieveCount = async () => {
await new Promise(resolve => {
setTimeout(() => {
resolve(undefined)
}, 500)
})
setCount(10)
}
retrieveCount()
}, [])
return count
}
If we wanted to try and waitFor
count to be 10, there doesn’t appear to be a way to do this with testing-library/react-native
as we can with the others:
it('waits until count has been set', async () => {
const { result } = renderHook(() => useCount())
// this line will always fail. `result.current` is always 0, no matter the options/rerendering/etc
await waitFor(() => expect(result.current).toBe(10))
// this syntax will also seemingly not do anything, which worked previously in the react-hooks library
await waitFor(() => result.current === 10)
expect(true).toBeTrue()
})
The above example will work just fine in testing-library/react
, however.
Screenshots
Versions
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 9
- Comments: 20 (6 by maintainers)
@bkdev98 I made the following changes in your test and it now works
As @mdjastrzebski mentioned the callback provided to waitFor should throw when the expectation is not met and also since you have a setTimeout of 2000ms, you need to increase the waitFor timeout which is of 1000ms per default so that fake timers are advanced by 2000ms, else it will timeout after 1000s
Please try this with @testing-library/react-hooks
We probably should revisit the documentation on waitFor, it says that the default timeout is 4500ms which is false and it does not clearly state that the expectation should throw so that it may work. Also I think it would be nice to mention that it behaves differently when using fake timers
It works!! Thank you for your help! ❤️
Looks like I’m no longer able to reproduce the issue with v11.2.0, thanks for all the collaboration on this! Apologies for my slow responses, I’ll try to help out more moving forward with this repo if I can
@kylebake can you confirm if this issue persists with RNTL v11.2.0?
@mdjastrzebski sure I’ll try to submit a pr by the end of the week
@bkdev98 you should use
waitFor
with an expectation, i.e. something that throws when the expectation is failed. Returningfalse
does not work, aswaitFor
considers that a legit return value.That should be relatively easy to fix:
@bkdev98 if that does not fix the issue for you, please adjust your code to use
except
as shown above and create a new GH issues for your case.Happy to help out and dig more into it 👍 I’m in the process of upgrading react-native for our app, which is why I’m uncovering some of this. I’ll let you know if I find anything over this week
@kylebake RNTL implementation of both
renderHook
&waitFor
closely matches React/Dom Testing Library one (essentially it probably is copy+paste+tweak), with minimal changes due to using React Test Renderer instead of React DOM renderer and not using having Js DOM objects likedocument
.If you have a bit of spare time and interest, you could try running diff for
renderHook
andwaitFor
source files between RNTL & RTL maybe this will shed some light why RTL’s version is working and RNTL’s version is not.