![](/img/trans.png)
[英]How to set component's local state while testing using jest and react-testing-library?
[英]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.