admin管理员组文章数量:1289530
I have a useEffect hook that loads when the ponent is mounted, as so:
useEffect(() => {
listFiles().then(keys => {
setKeys(keys)
console.log(keys)
}).catch(err => {
showFail(err.message)
})
}, [])
I'm trying to test the function with react testing-library, simply using the render function:
beforeEach(() => {
render(<Dashboard />)
})
However, when I run any test that resolves the promise and sets the state:
jest.mock('../utils/storage', () => ({
listFiles: jest.fn(() => Promise.resolve([])),
}))
I end up with a weird warning message about using act
to to wrap the event:
Warning: An update to Dashboard inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
This ensures that you're testing the behavior the user would see in the browser. Learn more at ..
in Dashboard
18 | useEffect(() => {
19 | listFiles().then(keys => {
> 20 | setKeys(keys)
| ^
21 | console.log(keys)
22 | }).catch(err => {
23 | showFail(err.message)
I have tried wrapping the render in an act
, but it doesn't seem to change anything.
Any suggestions as to what I'm doing wrong here? Should I be rendering in some other way?
Thanks in advance!
I have a useEffect hook that loads when the ponent is mounted, as so:
useEffect(() => {
listFiles().then(keys => {
setKeys(keys)
console.log(keys)
}).catch(err => {
showFail(err.message)
})
}, [])
I'm trying to test the function with react testing-library, simply using the render function:
beforeEach(() => {
render(<Dashboard />)
})
However, when I run any test that resolves the promise and sets the state:
jest.mock('../utils/storage', () => ({
listFiles: jest.fn(() => Promise.resolve([])),
}))
I end up with a weird warning message about using act
to to wrap the event:
Warning: An update to Dashboard inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
This ensures that you're testing the behavior the user would see in the browser. Learn more at ..
in Dashboard
18 | useEffect(() => {
19 | listFiles().then(keys => {
> 20 | setKeys(keys)
| ^
21 | console.log(keys)
22 | }).catch(err => {
23 | showFail(err.message)
I have tried wrapping the render in an act
, but it doesn't seem to change anything.
Any suggestions as to what I'm doing wrong here? Should I be rendering in some other way?
Thanks in advance!
Share Improve this question asked May 4, 2020 at 14:46 SamSam 1,3044 gold badges18 silver badges36 bronze badges2 Answers
Reset to default 7This error usually happens when you try to assert before the ponent has finished updating all state.
Note that inside listFiles
you are calling setKeys(keys)
and that updates the state.
You should await
for the new keys(or files) to show up in the document:
expect(await findByText('some file name or key')).toBeInTheDocument();
// more asserts here
Alternatively, you can waitFor the mock to have been called (although I think the option above is better).
await waitFor(() => expect(listFilesMock).toHaveBeenCalled());
// more asserts here
The methods above should already be wrapped in act
for you by the React Testing Library, so you don't need to do it
What is act()
from the React docs:
When writing UI tests, tasks like rendering, user events, or data fetching can be considered as “units” of interaction with a user interface. React provides a helper called act() that makes sure all updates related to these “units” have been processed and applied to the DOM before you make any assertions.
The name act es from the Arrange-Act-Assert pattern.
Useful links:
- Fix act warning by React Testing Library author
- React Act docs
In my case I wasn't mocking the useEffect async function.
ponent.test.tsx:
test('Working useEffect hook', () => {
const dbCallMock = jest.fn(() => Promise.resolve())
render(<Tracks dbCallMock ={dbCallMock} />)
}
ponent.tsx:
export const myComponent = (props: {
dbCallMock: Function
}) => {
const [state, setState] = useState<string[]>([])
const getDbState= () =>
db.state.toArray().then(gotState => setState(gotState))
useEffect(
() => (props.dbCallMock ? props.dbCallMock() : getDbState()),
[]
)
}
版权声明:本文标题:javascript - React testing-library - Testing a promise that set states in the first useEffect hook - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741428617a2378223.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论