简体   繁体   English

React testing-library - 测试在第一个 useEffect 挂钩中设置状态的 promise

[英]React testing-library - Testing a promise that set states in the first useEffect hook

I have a useEffect hook that loads when the component is mounted, as so:我有一个在安装组件时加载的 useEffect 钩子,如下所示:

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:我正在尝试使用反应测试库测试 function,只需使用渲染 function:

beforeEach(() => {
  render(<Dashboard />)
})

However, when I run any test that resolves the promise and sets the state:但是,当我运行任何解决 promise 并设置 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:我最终收到一条关于使用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)

I have tried wrapping the render in an act , but it doesn't seem to change anything.我曾尝试将渲染包装在一个act中,但它似乎并没有改变任何东西。

Any suggestions as to what I'm doing wrong here?关于我在这里做错了什么有什么建议吗? Should I be rendering in some other way?我应该以其他方式渲染吗?

Thanks in advance!提前致谢!

This error usually happens when you try to assert before the component has finished updating all state.当您在组件完成更新所有 state 之前尝试断言时,通常会发生此错误。

Note that inside listFiles you are calling setKeys(keys) and that updates the state.请注意,在listFiles中,您正在调用setKeys(keys)并更新 state。

You should await for the new keys(or files) to show up in the document:您应该await新密钥(或文件)出现在文档中:

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上面的方法act已经被 React 测试库为你包装好了,所以你不需要这样做


What is act() from the React docs : React文档中的act()是什么:

When writing UI tests, tasks like rendering, user events, or data fetching can be considered as “units” of interaction with a user interface.在编写 UI 测试时,渲染、用户事件或数据获取等任务可以被视为与用户界面交互的“单元”。 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. React 提供了一个名为 act() 的帮助器,它确保在您做出任何断言之前,与这些“单元”相关的所有更新都已被处理并应用于 DOM。

The name act comes from the Arrange-Act-Assert pattern.名称 act 来自 Arrange-Act-Assert 模式。


Useful links:有用的链接:

In my case I wasn't mocking the useEffect async function.在我的情况下,我不是 mocking useEffect async function。

component.test.tsx:组件.test.tsx:

test('Working useEffect hook', () => {
  const dbCallMock = jest.fn(() => Promise.resolve())
  render(<Tracks dbCallMock ={dbCallMock} />)
}

component.tsx:组件.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.

相关问题 测试库反应模拟 function 与回调将设置 state 返回 - testing-library react mock function with callback that will set state on return React Native Enzyme 测试 useEffect 钩子测试 - React Native Enzyme testing useEffect hook testing @testing-library/react 中的 toBeInTheDocument 和 getBy* 有什么区别 - Whats the difference between toBeInTheDocument and getBy* in @testing-library/react 使用 Jest 和 @testing-library/react-hooks 在 TypeScript 中单元测试自定义 React Hook - Unit Testing Custom React Hooks in TypeScript using Jest and @testing-library/react-hooks 反应测试 | 从“@testing-library/user-event”导入 userEvent 会生成错误“toBeInTheDocument 不是函数” - React Testing | importing userEvent from '@testing-library/user-event' generates error "toBeInTheDocument is not a function" useFakeTimers 在玩笑/测试库中不起作用 - useFakeTimers not working in jest/testing-library 自定义 React 组件库 - 开玩笑“找不到模块反应”- 测试库,汇总 - Custom React Component Library - jest 'cannot find module react'- testing-library, rollup 测试库自定义查询打字稿错误 - Testing-library custom query Typescript error 在 React / testing-library/react 中呈现所有组件后,如何从表中获取元素? - How to get the elements from a table after all components are rendered in React / testing-library/react? 使用@testing-library/react 对 react-router 的链接进行最简单的测试 - Simplest test for react-router's Link with @testing-library/react
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM