如何测试React组件仅在布尔标记为true时渲染指定JSX元素
如何让TestComponent初始渲染时显示Modal并测试其DOM?
首先先修正你代码里的两处小错误:
- 组件里的
isOpen应该是showModal,否则会因未定义变量报错 - 测试代码里的
discribe是拼写错误,应该是describe;toBeInTheDocument后面缺少括号,正确写法是toBeInTheDocument()
修正后的原组件:
const TestComponent = () => { const [showModal, setShowModal] = useState(false); return ( <> <button onClick={() => setShowModal(true)} > Show Modal </button> { showModal ? <Modal>...</Modal> : <div>No Modal</div>} </> ) }
修正后的测试代码框架:
describe("Rendered TestComponent", () => { it("has Modal component", () => { render(<TestComponent />); expect(screen.getByRole('input', {name: 'first-name' })).toBeInTheDocument(); }) })
下面给你三种实现初始渲染Modal的方案:
方案一:修改组件支持外部传入初始状态(推荐)
这种方式不仅能满足测试需求,还能让组件更灵活,后续业务中如果需要默认显示Modal也能直接复用。只需要给组件加一个可选props,用它作为useState的初始值:
修改后的组件:
const TestComponent = ({ initialShowModal = false }) => { const [showModal, setShowModal] = useState(initialShowModal); return ( <> <button onClick={() => setShowModal(true)} > Show Modal </button> { showModal ? <Modal>...</Modal> : <div>No Modal</div>} </> ) }
对应的测试代码:
describe("Rendered TestComponent", () => { it("renders Modal when initialShowModal is true", () => { // 直接传入初始状态为true,组件会直接渲染Modal render(<TestComponent initialShowModal={true} />); // 验证Modal内的目标输入框存在 expect(screen.getByRole('input', {name: 'first-name' })).toBeInTheDocument(); }) })
方案二:测试中模拟按钮点击(无需修改组件)
如果不想改动组件代码,可以在测试里模拟用户点击"Show Modal"按钮,触发状态切换后再进行断言:
import { fireEvent } from '@testing-library/react'; describe("Rendered TestComponent", () => { it("renders Modal after clicking show button", () => { render(<TestComponent />); // 找到显示按钮并模拟点击 const showButton = screen.getByText('Show Modal'); fireEvent.click(showButton); // 此时Modal已渲染,验证输入框存在 expect(screen.getByRole('input', {name: 'first-name' })).toBeInTheDocument(); }) })
方案三:Mock useState直接修改状态(不推荐)
这种方式属于"作弊式"测试,直接绕过组件逻辑修改useState的返回值,虽然能实现需求,但会破坏组件的真实行为逻辑,不建议在常规测试中使用:
describe("Rendered TestComponent", () => { it("renders Modal by mocking useState", () => { // mock React的useState,让它初始返回[true, 空函数] jest.mock('react', () => ({ ...jest.requireActual('react'), useState: jest.fn(() => [true, jest.fn()]) })); render(<TestComponent />); expect(screen.getByRole('input', {name: 'first-name' })).toBeInTheDocument(); // 测试完成后恢复mock,避免影响其他测试用例 jest.restoreAllMocks(); }) })
内容的提问来源于stack exchange,提问作者emptyfullstack
相关产品推荐
相关产品推荐

