-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Recommendation on testing #270
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
Right now it’s recommended to clear the query cache after each test, so what if the timeout or rerender checked to see if the query still exists in the cache or is mounted. Would that work?
…On Mar 20, 2020, 1:40 PM -0600, Kent C. Dodds ***@***.***>, wrote:
Hey there 👋
I'm getting an act warning when using react-query hooks because of this:
https://github.com/tannerlinsley/react-query/blob/df4bd3b54943db6acc4df612e6e85d6b09ea1a29/src/queryCache.js#L228-L237
Basically what's happening is my component finishes rendering and then react-query triggers a re-render (thanks to this) which is the thing that's giving me the act warning.
Now I can add an await waitFor(() => {}) call to the end of my test and the warning goes away, but I think it would be better to have an assertion in that callback. I'm just not sure what to assert happened as a result of the state update.
Do you have any suggestions for people testing this stuff? Should I just set the staleTime to Infinity? Kinda thinking that might work except then my tests would have a different config from my app which could lead to some problems.
Any ideas?
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
I think this would help! |
Yes, I just tried this and it worked well for me: // added to queryCache code in `dispatch` function:
// right above this line: https://github.com/tannerlinsley/react-query/blob/df4bd3b54943db6acc4df612e6e85d6b09ea1a29/src/queryCache.js#L223
if (!queryCache.getQuery(query.queryKey)) {
return
}
// in my test file:
afterEach(() => {
queryCache.clear()
}) And that worked. However, I observed that if I put that Either way, I think adding that if check to the dispatch function would be necessary. I also did notice that the Still working through this... |
Question... Why are we triggering a re-render anyway? |
It uses a redux style subscription architecture. The render reconciles new mutable state changes into the ui. We may not need this in the future with useMutableSource
…On Mar 20, 2020, 4:13 PM -0600, Kent C. Dodds ***@***.***>, wrote:
Question... Why are we triggering a re-render anyway?
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
Whoops, didn't mean to close |
I thought it was something like that... I'm just trying to think of whether there's anything I can assert so I can put that within the |
Yeah the idea of a stale query is not a ui bound variable by any means.
…On Mar 20, 2020, 4:18 PM -0600, Kent C. Dodds ***@***.***>, wrote:
I thought it was something like that...
I'm just trying to think of whether there's anything I can assert so I can put that within the waitFor(() => {/* expect right here */}) but there's nothing observable in the DOM that changes here and I can't think of anything in the query cache I could assert either... Hmmm....
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
I'm making a PR for the dispatch thing right now :) |
I am still investigating an issue related to this and I've isolated it down to iteraction between two tests. When each one runs individually, they pass, but when run together, the second fails. If I call There seems to be cleanup that needs to happen besides just clearing cache (listeners?) and it doesn't seem to happen with RTL's auto-cleanup functionality. I'm hoping to reproduce minimally to figure out what requires an explicit I plan to open an issue once I can reproduce in tests. Update: This may be an issue with our usage and with queries used within a |
Sounds like a race condition. Something goes wrong before the auto cleanup has a chance to run. |
@kentcdodds OK, I figured it out! It's an issue related to the way The reason my tests pass in my suite if I use RTL's
Notice the key here: it flushes the microtask queue. Since I call I went ahead and linked a one-line change to RTL and tested this new cleanup function:
Suddenly all my tests passed 😄 This runs the unmount first then flushes any remaining microtasks that may have been queued as part of the unmount process. So now I can try to write a test case(s) to reproduce this within RTL itself and hopefully submit a PR, unless you feel this is enough information. edit: I have a test case I'll submit in a PR. test('cleanup waits for queued microtasks during unmount sequence', async () => {
const spy = jest.fn()
const Test = () => {
React.useEffect(() => () => setImmediate(spy))
return null
}
render(<Test />)
await cleanup()
expect(spy).toHaveBeenCalledTimes(1)
}) |
Update: I was able to isolate this to react-query only when I will open a draft PR to showcase it and then try to nail down a fix, if possible. |
Was having same behaviour with Based on feedback found in this thread, I create custom factory for creating hook's wrapping component which tells Jest to clear query AND mutation cache after each test. import React from 'react';
import {addCleanup} from '@testing-library/react-hooks';
import {
MutationCache,
QueryCache,
QueryClient,
QueryClientProvider,
} from 'react-query';
/**
* Wrapper component providing Query context.
*/
export function createQueryWrapper() {
const mutationCache = new MutationCache();
const queryCache = new QueryCache();
const queryClient = new QueryClient({
queryCache,
mutationCache,
defaultOptions: {
queries: {
retry: false,
},
},
});
const wrapper: React.FC = (props) => {
return (
<QueryClientProvider client={queryClient}>
{props.children}
</QueryClientProvider>
);
};
addCleanup(() => {
mutationCache.clear();
queryCache.clear();
});
return {
queryClient,
wrapper,
};
} |
Hi @Andreyco and thanks for offering an out of the box solution to those warning, I wanted to copy the code but I am using |
@kopax Least you could do is // @ts-expect-error
import {addCleanup} from '@testing-library/react-hooks'; |
why not just give every test their own QueryClien? this will get rid of the need for any cleanup. something like this:
|
That is exactly what the snippet I posted does. If you care about query client in test, you have it exported. In addition, it does repetitive work for you 🤷♂️ |
Is it expected to still see the Versions:
|
Hey there 👋
I'm getting an
act
warning when using react-query hooks because of this:https://github.com/tannerlinsley/react-query/blob/df4bd3b54943db6acc4df612e6e85d6b09ea1a29/src/queryCache.js#L228-L237
Basically what's happening is my component finishes rendering and then react-query triggers a re-render (thanks to this) which is the thing that's giving me the act warning.
Now I can add an
await waitFor(() => {})
call to the end of my test and the warning goes away, but I think it would be better to have an assertion in that callback. I'm just not sure what to assert happened as a result of the state update.Do you have any suggestions for people testing this stuff? Should I just set the
staleTime
toInfinity
? Kinda thinking that might work except then my tests would have a different config from my app which could lead to some problems.Any ideas?
The text was updated successfully, but these errors were encountered: