![](/img/trans.png)
[英]testing-library react mock function with callback that will set state on return
[英]React testing-library - Testing a promise that set states in the first useEffect hook
我有一个在安装组件时加载的 useEffect 钩子,如下所示:
useEffect(() => {
listFiles().then(keys => {
setKeys(keys)
console.log(keys)
}).catch(err => {
showFail(err.message)
})
}, [])
我正在尝试使用反应测试库测试 function,只需使用渲染 function:
beforeEach(() => {
render(<Dashboard />)
})
但是,当我运行任何解决 promise 并设置 state 的测试时:
jest.mock('../utils/storage', () => ({
listFiles: jest.fn(() => Promise.resolve([])),
}))
我最终收到一条关于使用act
来包装事件的奇怪警告消息:
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)
我曾尝试将渲染包装在一个act
中,但它似乎并没有改变任何东西。
关于我在这里做错了什么有什么建议吗? 我应该以其他方式渲染吗?
提前致谢!
当您在组件完成更新所有 state 之前尝试断言时,通常会发生此错误。
请注意,在listFiles
中,您正在调用setKeys(keys)
并更新 state。
您应该await
新密钥(或文件)出现在文档中:
expect(await findByText('some file name or key')).toBeInTheDocument();
// more asserts here
或者,您可以等待模拟已被调用(尽管我认为上面的选项更好)。
await waitFor(() => expect(listFilesMock).toHaveBeenCalled());
// more asserts here
上面的方法act
已经被 React 测试库为你包装好了,所以你不需要这样做
act()
是什么:在编写 UI 测试时,渲染、用户事件或数据获取等任务可以被视为与用户界面交互的“单元”。 React 提供了一个名为 act() 的帮助器,它确保在您做出任何断言之前,与这些“单元”相关的所有更新都已被处理并应用于 DOM。
名称 act 来自 Arrange-Act-Assert 模式。
在我的情况下,我不是 mocking useEffect async function。
组件.test.tsx:
test('Working useEffect hook', () => {
const dbCallMock = jest.fn(() => Promise.resolve())
render(<Tracks dbCallMock ={dbCallMock} />)
}
组件.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()),
[]
)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.