【问题标题】:How to test logic using a ref and updating state inside useEffect/useLayoutEffect with react-testing-library如何使用 ref 测试逻辑并使用 react-testing-library 更新 useEffect/useLayoutEffect 中的状态
【发布时间】:2021-04-01 11:27:56
【问题描述】:

我的组件利用useLayoutEffect 执行一个函数来计算两个状态变量的位置。将相同的函数传递给内部容器之一的 Element.scroll 事件:

代码如下所示:

export const Component = ({children}) => {
    // .....

    const containerRef = useRef<HTMLDivElement>(null);
    const [canClickLeft, setCanClickLeft] = useState(false);
    const [canClickRight, setCanClickRight] = useState(false);

    const checkForPosition = () => {
      if (containerRef.current) {
        // logic here;

        const positionLeft = false;
        const positionRight = true;
  
        setCanClickLeft(positionLeft);
        setCanClickRight(positionRight);
      }
    };

    const doSomething = () = {....}
  
    useLayoutEffect(() => {
        checkForPosition();
    });


    return (
      <>
        <StyledContainer onScroll={() => checkForPosition()}>
          {children}
        </StyledContainer>
  
        <button disabled={!canClickLeft} onClick={doSomething}>Click Left</button>
        <button disabled={!canClickRight onClick={doSomething}}>Click Right</button>
      </>
    );
};

我对上述代码行做了一个简单的测试:

test('flow', () => {
  const {asFragment, getByTestId} = render(<Component />)

  expect(asFragment()).toMatchSnapshot();
  expect(getByText('Click Left')).toBeDisabled();
  expect(getByText('Click Right')).toBeEnabled();
});

不幸的是,jest 抛出错误并显示以下错误消息:

expect(element).toBeEnabled()
Received element is not enabled: <button disabled=""/>

有人能解释一下这个错误的本质吗?测试这个组件的正确方法是什么?

编辑:主要问题似乎是测试中渲染时的未知参考。

看起来其他人也在为此苦苦挣扎: https://spectrum.chat/testing-library/general/testing-useeffect-with-usestate-and-useref-inside~168a4df3-e2cd-486d-b908-e1f67c87b7be

Edit2:另一个相关线程How to test useRef with Jest and react-testing-library?

Edit3:好的,参考实际上在那里并且可以访问 https://rafaelquintanilha.com/react-testing-library-common-scenarios/#scenario-3---focused-element

【问题讨论】:

    标签: reactjs react-hooks react-testing-library


    【解决方案1】:

    在被这个难题困住了几天之后,我想我找到了为什么我的测试失败了。

    checkForPosition 函数内部的逻辑主要处理在引用的 dom 元素内访问的元素属性,如 clientHeight、clientWidth、scrollHeight、scrollWidth、offsetWidth、offsetHeight 等。

    React Testin Library 依靠 JSDOM 来“渲染” React Web 组件,但 JSDOM 在其本质上不支持布局。在我的测试中,所有这些维度测量值都等于 0。

    https://github.com/testing-library/react-testing-library/issues/353#issuecomment-481248489

    所以我尝试模拟根本不适合我的 useRef 函数:

    尝试使用 act 之类的函数来更好地重现 react 组件循环,尝试使用计时器的异步代码,但仍然无法使其工作:

    最后决定只是模拟元素的 props 并以某种方式拦截引用的 dom 组件:

    其他资源: https://kentcdodds.com/blog/react-hooks-whats-going-to-happen-to-my-tests

    使 useEffect 钩子同步运行以使测试更好:https://twitter.com/kentcdodds/status/1064023833189900288?lang=en

    【讨论】:

      猜你喜欢
      • 2020-03-26
      • 2020-05-10
      • 2019-08-29
      • 2021-11-30
      • 2019-05-21
      • 2019-11-11
      • 2019-10-30
      • 2020-01-09
      • 2023-04-04
      相关资源
      最近更新 更多