-
Notifications
You must be signed in to change notification settings - Fork 232
Warning about using different versions of act() when wait()ing on an async effect #173
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
Hi @pelotom, The issue here is that you are using You could follow our docs on how to handle async with the |
Thanks @mpeyper I don't get why someone would downvote an answer that both explains the issue and provides a solution! ¯_(ツ)_/¯ |
Haha, yeah... not sure either. I guess I'll just have to issue them a refund for the licensing fees to use the library 😅 |
I've followed the documentation for handling async hooks. But I'm still receiving the same warning that I'm using act() even though I'm no longer using act() in the test function now as per the documentation,
describe('hooks', () => {
it('getProjects', async () => {
const { result, waitForNextUpdate } = renderHook(() => useProjects());
expect(Array.isArray(result.current.projects)).toBeTruthy();
expect(result.current.projects.length).toBe(0);
result.current.getProjects();
await waitForNextUpdate();
expect(result.current.projects.length > 0).toBeTruthy();
});
}); |
Hi @tyeon95, Sorry to hear you're also having problems with and Everything in the test you've shared looks to correct, so I'm not sure what this issue might be. Are you able to share the code for your Also, you've listed the react version for Last thing. The version for |
some problem
demo like this // api.ts
import { message } from 'antd'
import { useHistory } from 'react-router-dom'
// generated by graphql-code-generator
// https://graphql-code-generator.com/docs/plugins/typescript-react-apollo
import { useLoginMutation } from './generated'
function useLoginApi() {
const history = useHistory()
const [loginMutation, { loading }] = useLoginMutation()
const submit = async (pwd: string, phone: string) => {
try {
const { data } = await loginMutation({
variables: {
phone,
pwd,
},
})
if (data?.login?.role !== 5) {
message.error('no auth')
return
}
message.success('success')
history.replace('/home')
} catch (e) {
message.error('error')
}
}
return {
loading,
submit,
}
}
// api.test.tsx
import React from 'react'
import { MemoryRouter as Router } from 'react-router-dom'
import { renderHook, act } from '@testing-library/react-hooks'
import { MockedProvider, MockedResponse } from '@apollo/react-testing'
import { useLoginApi } from './api'
import { LoginDocument } from './generated'
interface MockedProps {
children?: any
}
const mooks: MockedResponse[] = [
{
// success
request: {
query: LoginDocument,
variables: { phone: 18812345678, pwd: '123456' },
},
result: {
data: {
login: {
id: 'id',
token: 'token',
role: 5,
nickname: 'nickname',
},
},
},
},
]
it('useLoginApi', async () => {
const { result, waitForNextUpdate } = renderHook(() => useLoginApi(), {
wrapper: ({ children }: MockedProps) => (
<Router>
<MockedProvider mocks={mooks}>{children}</MockedProvider>
</Router>
),
})
expect(result.current.loading).toEqual(false)
// Warning: An update to TestHook inside a test was not wrapped in act(...).
act(() => {
result.current.submit('123456', '18812345678')
})
expect(result.current.loading).toEqual(false)
})
it('useLoginApi', async () => {
const { result, waitForNextUpdate } = renderHook(() => useLoginApi(), {
wrapper: ({ children }: MockedProps) => (
<Router>
<MockedProvider mocks={mooks}>{children}</MockedProvider>
</Router>
),
})
expect(result.current.loading).toEqual(false)
result.current.submit('123456', '18812345678')
// Warning: An update to TestHook inside a test was not wrapped in act(...).
await waitForNextUpdate()
expect(result.current.loading).toEqual(false)
})
it('useLoginApi', async () => {
const { result, waitForNextUpdate } = renderHook(() => useLoginApi(), {
wrapper: ({ children }: MockedProps) => (
<Router>
<MockedProvider mocks={mooks}>{children}</MockedProvider>
</Router>
),
})
expect(result.current.loading).toEqual(false)
result.current.submit('123456', '18812345678')
// Warning: It looks like you're using the wrong act() around your test interactions.
act(() => {
result.current.submit('123456', '18812345678')
})
await waitForNextUpdate()
expect(result.current.loading).toEqual(false)
}) |
I've been able to reproduce this with the help of @qiwang97's example (I had to make up what was in You can check out the sandbox here if you want to double check anything or make any suggestions for things to change. The console output clearly shows the warning message being presented on the Interesting, as the example actually returns the promise, it is possible to write this test to avoid the use of expect(result.current.loading).toEqual(false)
await act(() => result.current.submit('123456', '18812345678'))
expect(result.current.loading).toEqual(false) This is basically the same way that It's late now, so I'm going go to bed now, but next time I have some time (likely sometime this weekend), I'm going to set up a basic example that renders a component with a hook using pure Annoyingly, I don't see the same warning when I run the test suite for this library, so I don't think I'll see the warning when just using pure |
Ok @qiwang97, got something, but not sure what it means yet. If I comment out the I've taken a look at the |
I've yet to confirm it (out of time today), but I believe it's happening because the underlying |
Ok, can confirm, if I hack my Interestingly, it appears as though they have the functionality to provide an alternative I'm closing this now as I cannot force every library to never call // api.ts
import { message as antdMessage } from 'antd'
import { useHistory } from 'react-router-dom'
// generated by graphql-code-generator
// https://graphql-code-generator.com/docs/plugins/typescript-react-apollo
import { useLoginMutation } from './generated'
function useLoginApi({ message = antdMessage } = {}) {
const history = useHistory()
const [loginMutation, { loading }] = useLoginMutation()
const submit = async (pwd: string, phone: string) => {
try {
const { data } = await loginMutation({
variables: {
phone,
pwd,
},
})
if (data?.login?.role !== 5) {
message.error('no auth')
return
}
message.success('success')
history.replace('/home')
} catch (e) {
message.error('error')
}
}
return {
loading,
submit,
}
} |
@mpeyper Thanks a lot and I will try. |
yes @mayacode, this appears to be the exact same issue with |
Thanks a lot, I started to align our test and I mock the problematic stuff. It needs some additional work but I decreased the number of warnings with keeping the test coverage. Thank you again! |
For me, using
instead of
solved the problem. |
@testing-library/react-hooks
version: 2.0.1react-test-renderer
version: 16.9.0react
version: 16.9.0node
version: 12.9.0npm
(oryarn
) version: 1.17.3 (yarn)Relevant code or config:
What you did:
Tried to augment the example test in the README with an asynchronous effect.
What happened:
Although the test passes I get a warning about using differing versions of
act()
:The text was updated successfully, but these errors were encountered: