如何测试该组件与React测试库原理保持一致?
我正在测试一个组件,并想知道最好的方法是在没有测试实现细节的情况下测试组件。
该组件根据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()
})
谢谢!
I am testing a component and wondering what the best approach would be that would test the component without testing implementation details.
The component renders conditionally based on the width
and isDropdown
state, but not sure how to test how the DOM would look by changing these values or even if that would be the correct approach.
Here is the component:
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
Here is my initial test that is only testing if the text properly appears in the DOM, which it does:
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()
})
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我会为
feed
的每组道具编写测试,一个测试嘲笑setFeedChoice
props props并断言其呼叫:因此,您正在登台
feed 组件,您可以测试它仅在输入(Prop)和输出(DOM生成,下拉开放,文本,回调调用)方面的行为。您不仅测试内部实现,而只能测试进出的内容。
困难的部分可能是与下拉菜单正确交互并使其正确打开/关闭。您可能必须使用
waitfor
,或者by
fireevent
(根据我的经验,有时fireeevent
更可靠 - 但不太现实)。 See React Testing Library: When使用userevent.click并何时在此主题上使用fireevent 。I would write tests for each set of props for
Feed
, and one test mocking thesetFeedChoice
props and asserting on its calls :Therefore you are staging the
Feed
component, and you test how it behaves regarding only inputs (props) and outputs (DOM generated, dropdown opening, texts, callback calls). You don't test internal implementation, only what's in and out.The difficult part may be to interact correctly with the dropdown and make it open/close correctly. You may have to use
waitFor
, or replaceuserEvent
byfireEvent
(in my experience sometimesfireEvent
is more reliable - but less realistic). See React Testing Library: When to use userEvent.click and when to use fireEvent on this subject.