如何使用react-testing-library使用ref测试逻辑并更新useEffect/useLayoutEffect内的状态

pol*_*llx 2 reactjs react-testing-library react-hooks

我的组件用于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>
      </>
    );
};
Run Code Online (Sandbox Code Playgroud)

我对上述代码行进行了简单的测试:

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

  expect(asFragment()).toMatchSnapshot();
  expect(getByText('Click Left')).toBeDisabled();
  expect(getByText('Click Right')).toBeEnabled();
});
Run Code Online (Sandbox Code Playgroud)

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

expect(element).toBeEnabled()
Received element is not enabled: <button disabled=""/>
Run Code Online (Sandbox Code Playgroud)

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

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

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

Edit2:另一个相关线程如何使用 Jest 和react-testing-library 测试 useRef?

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

pol*_*llx 5

After being stuck in this conundrum for a few days I think I found out why I got the failing tests.

The logic inside the checkForPosition functions deals heavily with element properties like clientHeight, clientWidth, scrollHeight, scrollWidth, offsetWidth, offsetHeight etc. accessed inside the referenced dom element.

React Testin Library realies on JSDOM to 'render' react web components but JSDOM doesn't support layout in its escennce. All these dimension mesaruments equal 0 everywhere in my tests.

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

So I tried mocking the useRef function which didn't work for me at all:

Tried to use functions like act to better reprodice the react component cycle, tried async code with timers, but still couldn't make it work:

At the end decided to just mock the element's props and somehow intercept the referenced dom component:

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

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


归档时间:

查看次数:

3933 次

最近记录:

4 年,11 月 前