繁体   English   中英

如何测试这个组件与 React 测试库原则保持一致?

[英]How to test this component staying aligned with React Testing Library Principles?

我正在测试一个组件,并想知道在测试实现细节的情况下测试组件的最佳方法是什么。

组件根据widthisDropdown状态有条件地呈现,但不确定如何通过更改这些值来测试 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM