-
Notifications
You must be signed in to change notification settings - Fork 272
renderHook
result values with waitFor
not working
#1030
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@kylebake RNTL implementation of both If you have a bit of spare time and interest, you could try running diff for |
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 |
A bit more info while I'm still investigating: it definitely appears to be that If you take the example hook from my first comment, and test it with this code, const { result, rerender } = setupHook()
setInterval(() => {
console.log(`result: ${result.current}`)
}, 1000)
await waitFor(() => expect(result.current).toBe(10), { timeout: 15000 }) However, running the following test, let count = 0
setTimeout(() => {
count = 10
}, 3000)
await waitFor(() => expect(count).toBe(10), { timeout: 15000 }) I'm going to focus my attention on |
@kylebake I think the issue here is not with the renderHook implementation but rather that waitFor isn't able to wait for promises using timers, these promises are never resolved (see this other issue #1067). To fix it you can use fake timers, run the pending timer and then use waitFor to resolve the promise. Regarding waitFor not being able to handle this situation I'm not sure what's causing this but I wonder if it's not rather a jest issue |
@pierrezimmermannbam do you mean that |
The promises are resolving in my use cases, I'm able to set breakpoints and see the code get past the async logic. The tests don't seem to be able to see this, however. I'd also push back on it being a jest issue since I'm able to get all of this working without any code/jest changes if I use A super hacky workaround that I've found is to continuously update the component/hook in the test and only then can the
Sidenote: I can spend some more time on this issue this weekend, been busy with getting our react native version upgraded to unblock us. I'll get a small repo stood up as well so it's easier for us to test against. |
Please try this with @testing-library/react-hooks
|
@kylebake can you confirm if this issue persists with RNTL v11.2.0? |
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 |
Awesome, thanks for checking that @kylebake |
I'm still reproducing the problem in v11.2.0! |
@lubbo could you please post a repro using https://github.com/callstack/react-native-testing-library/tree/main/examples/basic please? Without that, we can't figure out what is happening, since the issue has been solved for most (it seems) users. Are you using react 18 by the way? Because there could still be problem with older versions of react, but I'm not sure we'll be able to prioritise work to fix them. |
Hi @AugustinLF here is my repro using the basic example: https://github.com/bkdev98/rn-testing-lib-waitfor-issue. The tests/asyncHooks.spec.tsx failed and |
@bkdev98 you should use That should be relatively easy to fix: await waitFor(() => expect(result.current).toBeTruthy()); @bkdev98 if that does not fix the issue for you, please adjust your code to use |
@bkdev98 I made the following changes in your test and it now works describe("useProductDetail", () => {
beforeEach(() => {
jest.useFakeTimers();
});
test("should instantly show initial product data", async () => {
jest.useFakeTimers();
const { result } = renderHook(() => useTestAsyncHook());
await waitFor(() => expect(result.current).toBe(true), { timeout: 2500 });
expect(result.current).toEqual(true);
});
}); 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 |
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! ❤️ |
@pierrezimmermannbam would you have time to update |
@mdjastrzebski sure I'll try to submit a pr by the end of the week |
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 specificallyreact-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 itSteps to Reproduce
Consider the following hook:
If we wanted to try and
waitFor
count to be 10, there doesn't appear to be a way to do this withtesting-library/react-native
as we can with the others:The above example will work just fine in
testing-library/react
, however.Screenshots
Versions
The text was updated successfully, but these errors were encountered: