【问题标题】:Test exception - unstable_flushDiscreteUpdates测试异常——unstable_flushDiscreteUpdates
【发布时间】:2020-07-04 17:33:23
【问题描述】:

我有一个使用 Jest 和 react-testing-library 和 .tsx 测试文件 (TypeScript) 的测试:

import React from "react";
import { Provider } from 'react-redux';
import { render, screen } from "@testing-library/react";
import Home from "./Home";
describe('Home', () => {
    test("renders Programs without crashing", async () => {
        const storeFake = (state: any) => ({
            default: () => { },
            subscribe: () => { },
            dispatch: () => { },
            getState: () => ({ ...state })
        });
        const store = storeFake({}) as any;
        const { getByAltText } = render(<Provider store={store}>
                                            <Home />
                                        </Provider>);
        // render should show the title
        expect(getByAltText(/Great State/)).toBeInTheDocument();
    });

测试通过但抛出异常:

console.error node_modules/react-dom/cjs/react-dom.development.js:88
  Warning: unstable_flushDiscreteUpdates: Cannot flush updates when React is already rendering.
      in video (at Home.tsx:10)
      in div (at Home.tsx:9)
      in Home (created by ConnectFunction)
      in ConnectFunction (at Home.test.tsx:15)
      in Provider (at Home.test.tsx:14)

首先,有谁知道如何解决异常。其次,我知道这是一个警告,但看起来很严重,测试不应该失败吗?

【问题讨论】:

    标签: reactjs typescript jestjs create-react-app react-testing-library


    【解决方案1】:

    正如错误消息所述,它是一个 React 警告,与 React 测试库无关。根据这个线程https://github.com/facebook/react/issues/10389,这实际上是一个 React 问题。当您使用具有 muted 属性的 &lt;video /&gt; 元素时,您可能会遇到此警告。

    您可以在beforeAll 块内或在执行测试用例之前尝试以下代码。

       Object.defineProperty(HTMLMediaElement.prototype, "muted", {
           set: jest.fn(),
       });
    

    假设您在组件中使用&lt;video /&gt; 标签,它应该可以工作,如下所示。

    <video src={videoPath} muted />
    

    【讨论】:

      【解决方案2】:

      属性与属性

      由于 React 设置了静音 property 而不是正确地将 attribute 传递给元素,因此出现此错误:第一个反映当前值,而后者反映 >组件的初始状态。因此,将muted 设置为道具会错误地触发事件。

      解决方案:您也可以在 useEffect 挂钩中设置“静音”属性

      function VideoComponent() {
          const videoRef = createRef<HTMLVideoElement>()
          const source = '/path/to.mp4'
      
          useEffect(() => {
              const { current: video } = videoRef
              video && (video.muted = true)
          }, [])
      
          return (
              <video 
                  ref={videoRef} 
                  src={source}
                  autoPlay loop playsInline  
                  />
          )
      
      }
      

      【讨论】:

      • 我真的很喜欢这个特殊的解决方案,因为它从问题的根源解决了问题。也谢谢你的解释!
      • 这个解决方案是我可以通过反应测试库测试的唯一方法,除了 const videoRef = createRef&lt;HTMLVideoElement&gt;() 我使用 const videoRef = useRef(null);
      猜你喜欢
      • 2014-07-07
      • 2011-01-28
      • 2012-09-27
      • 2016-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-18
      相关资源
      最近更新 更多