簡體   English   中英

如何使用 react-testing-library 和 jest 測試 function 組件中的 state

[英]How to test state within function component with react-testing-library and jest

我有一個要測試的組件 -

export const Block = ({ title }) => {
      const [isSmall, setIsSmall] = useState(false);
      

      reutrn (

            <BlockContainer
                  onBlockContainerResize={(width: number) => (width < 180 ? setIsSmall(true) : setIsSmall(false))}
            >
                  <div className={isSmall ? 'title--small' : 'title'} data-testid={isSmall ? 'isSmall' : ''}>
                        {title}
                  </div>
                  <div className={isSmall ? 'desc--small' : 'desc'}>
                        {desc}
                  </div>
            </BlockContainer>
      )
}

我添加了一個 data-testid,因為我想避免測試 classNames,因為這違反了 react-testing-library 原則。 我只想確保如果容器低於 180px,則 isSmall 設置為 true。

對於我的測試,我使用 div 作為容器而不是父組件BlockContainer -

test('should set isSmall to true if container width is below 180px', () => {
  render(
      <div style={{ width: '170px' }}>
        <Block
          title="test title"
          desc="test description"
        />
      </div>
  );

  expect(within(screen.getByTestId('isSmall')).queryByText('test title')).toBeInTheDocument();
});

但是,嘗試此操作時,isSmall 未設置為 true,因此未設置 datatest-id。 我很困惑為什么會這樣?

這是 BlockContainer 實現 -

export const BlockContainer: FunctionComponent<BlockContainerProps> = ({
  children,
  onBlockContainerResize,
}) => {
  const blockRef = useRef<HTMLDivElement>(null);

  useResizeObserver(blockRef, (entry) => onBlockContainerResize?.(entry.contentRect.width));

  return (
    <div
      ref={blockRef}
    >
      {children}
    </div>
  );
};

使用 React 測試庫進行測試時,了解其他組件的功能很重要。 例如,您將isSmall state 初始化為 false,並且僅在onBlockContainerResize的回調中將其設置為 true,但您沒有采取任何措施來實現這一點。 您需要觸發該回調以進行更改。

也就是說,在 RTL 中,主要目標是測試最終用戶看到的內容並模擬最終用戶所做的事情。 這意味着要觸發該回調,您需要模仿用戶行為(例如,調整容器大小)。 所以我們需要知道用戶是如何做到這一點的(在BlockContainer組件內部),然后在渲染組件之后和斷言之前使用來自 RTL 的fireEvent觸發它。

此外,我不會將data-testid屬性放在 div 中並根據 state 呈現它。這會將您的測試與組件的實現結合起來。 我會拿那個 div,並檢查它的大小,這是最終用戶會做的,因為用戶不知道內部狀態。

希望這些提示有所幫助。 如果沒有,我們將需要一個BlockContainer的實現示例來了解如何觸發此事件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM