[英]How to test react component with onClick function Jest/React testing library
[英]How to test this component staying aligned with React Testing Library Principles?
我正在测试一个组件,并想知道在不测试实现细节的情况下测试组件的最佳方法是什么。
组件根据width
和isDropdown
状态有条件地呈现,但不确定如何通过更改这些值来测试 DOM 的外观,或者即使这是否是正确的方法。
这是组件:
import { useState } from 'react'
import useWindowDimension from '../../hooks/useWindowDimensions'
import { QueryType } from '../../constants'
type choiceProps = {
type: QueryType
isChosen: boolean
setFeedChoice: (query: QueryType) => void
}
const FeedChoice = ({ type, isChosen, setFeedChoice }: choiceProps) => {
return (
<div
className={isChosen ? 'feed-choice chosen' : 'feed-choice'}
onClick={() => setFeedChoice(type)}
>
<img
src={require(`../../../public/images/${type}${
isChosen ? '-fill' : ''
}.svg`)}
/>
<span>{type.charAt(0).toUpperCase() + type.slice(1)}</span>
</div>
)
}
type Props = {
feedChoice: QueryType
setFeedChoice: (query: QueryType) => void
}
const Feed = ({ feedChoice, setFeedChoice }: Props) => {
const { width } = useWindowDimension()
const [isDropdown, setDropdown] = useState<boolean>(false)
const setChoice = (query: QueryType) => {
setFeedChoice(query)
setDropdown(false)
}
if (width !== null && width <= 600) {
return (
<div className="feed-row">
{isDropdown ? (
<div>
<FeedChoice
type={QueryType.New}
isChosen={feedChoice === QueryType.New}
setFeedChoice={setChoice}
/>
<FeedChoice
type={QueryType.Boost}
isChosen={feedChoice === QueryType.Boost}
setFeedChoice={setChoice}
/>
<FeedChoice
type={QueryType.Comments}
isChosen={feedChoice === QueryType.Comments}
setFeedChoice={setChoice}
/>
<FeedChoice
type={QueryType.Squash}
isChosen={feedChoice === QueryType.Squash}
setFeedChoice={setChoice}
/>
</div>
) : (
<FeedChoice
type={feedChoice}
isChosen={true}
setFeedChoice={() => setDropdown(true)}
/>
)}
</div>
)
} else {
return (
<div className="feed-row">
<FeedChoice
type={QueryType.New}
isChosen={feedChoice === QueryType.New}
setFeedChoice={setFeedChoice}
/>
<div className="divider"></div>
<FeedChoice
type={QueryType.Boost}
isChosen={feedChoice === QueryType.Boost}
setFeedChoice={setFeedChoice}
/>
<div className="divider"></div>
<FeedChoice
type={QueryType.Comments}
isChosen={feedChoice === QueryType.Comments}
setFeedChoice={setFeedChoice}
/>
<div className="divider"></div>
<FeedChoice
type={QueryType.Squash}
isChosen={feedChoice === QueryType.Squash}
setFeedChoice={setFeedChoice}
/>
</div>
)
}
}
export default Feed
这是我的初始测试,仅测试文本是否正确显示在 DOM 中,它确实如此:
import React from 'react'
import { screen, render } from '@testing-library/react'
import Feed from '../components/feed/feed'
import useWindowDimensions from '../hooks/useWindowDimensions'
test('should render all of the QueryTypes in the Feed', () => {
render(<Feed />)
expect(screen.getByText(/new/i)).toBeInTheDocument()
expect(screen.getByText(/boost/i)).toBeInTheDocument()
expect(screen.getByText(/comments/i)).toBeInTheDocument()
expect(screen.getByText(/squash/i)).toBeInTheDocument()
})
谢谢!
我会为Feed
的每一组 props 编写测试,一个测试setFeedChoice
props 并断言它的调用:
const setFeedChoiceMock = jest.fn();
test('calls callback correctly', () => {
render(<Feed feedChoice=... setFeedChoice={setFeedChoiceMock} />)
// click on whatever makes the drop down open
userEvent.click(...);
// click on one option
userEvent.click(screen.getByText(...));
// check that the callback was called
expect(setFeedChoiceMock).toHaveBeenCalledWith("expected parameter, option text...");
});
// write other tests changing the feedChoice props to ensure all cases work well
test('respects feedChoice props', () => {
render(<Feed feedChoice="other value" setFeedChoice={setFeedChoiceMock} />)
// check that feedChoice is correctly used
expect(screen.getByText(...)).toBeInTheDocument()
});
因此,您正在暂存Feed
组件,并测试它仅与输入(道具)和输出(DOM 生成、下拉打开、文本、回调调用)有关的行为。 您不测试内部实现,只测试进出的内容。
困难的部分可能是与下拉菜单正确交互并使其正确打开/关闭。 您可能必须使用waitFor
,或将userEvent
替换为fireEvent
(根据我的经验,有时fireEvent
更可靠 - 但不太现实)。 请参阅React 测试库:关于此主题的何时使用 userEvent.click 以及何时使用 fireEvent 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.