我正在使用一个会产生副作用的简单组件。我的测试通过了,但是我收到了Warning: An update to Hello inside a test was not wrapped in act(...).
警告。
我也不知道waitForElement
是否是编写此测试的最佳方式。
我的组件
export default function Hello() {
const [posts, setPosts] = useState([]);
useEffect(() => {
const fetchData = async () => {
const response = await axios.get('https://jsonplaceholder.typicode.com/posts');
setPosts(response.data);
}
fetchData();
}, []);
return (
<div>
<ul>
{
posts.map(
post => <li key={post.id}>{post.title}</li>
)
}
</ul>
</div>
)
}
我的组件测试
import React from 'react';
import {render, cleanup, act } from '@testing-library/react';
import mockAxios from 'axios';
import Hello from '.';
afterEach(cleanup);
it('renders hello correctly', async () => {
mockAxios.get.mockResolvedValue({
data: [
{ id: 1, title: 'post one' },
{ id: 2, title: 'post two' },
],
});
const { asFragment } = await waitForElement(() => render(<Hello />));
expect(asFragment()).toMatchSnapshot();
});
6条答案
按热度按时间6kkfgxo01#
更新的答案:
请参考下面的@mikaelrs评论。
不需要waitFor或waitForElement。你可以只使用findBy* 选择器,它返回一个可以等待的承诺。例如await findByTestId('list');
不建议使用的答案:
使用
waitForElement
是一种正确的方法,从docs:等待,直到模拟的
get
请求承诺解决,组件调用setState并重新呈现。waitForElement
等待,直到回调不抛出错误以下是您的案例的工作示例:
index.jsx
:index.test.jsx
:100%覆盖的单元测试结果:
index.test.jsx.snapshot
:源代码:https://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/60115885
nwo49xxi2#
对我来说,解决办法是等待
waitForNextUpdate
oxosxuxt3#
WaitFor
对我很有效,我试着使用这里提到的findByTestId
,但是我仍然得到同样的操作错误。我的解决方案:
m3eecexj4#
我有一个错误:
密码:
我决定:
我刚刚在回调fn - waitFor()中进行了 Package
也许会对某人有用
cfh9epnr5#
slideshowp 2上面的答案很好,但是非常具体地针对您的特定示例。(他的答案似乎不起作用,因为它没有等待axios的承诺来解决;总是存在
list
testid
,但这很容易修复。)如果您的代码发生了更改,例如,在找到
list
testId
之后,Assert运行,然后触发另一个useEffect
,这将导致您不关心的状态更新,您将再次遇到相同的act
问题。一个通用的解决方案是将render
Package 在act
中以确保在继续Assert和测试结束之前完成所有更新。这些Assert不需要waitFor
任何东西。重写测试主体如下:(从测试库导入
act
。)请注意,
render
被 Package 在act
中,并且使用getBy*
查找列表,这不是异步的!所有承诺解析都在getByTestId
调用之前完成,因此在测试结束后不会发生状态更新。wi3ka0sx6#
这对我有用。