You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Enzyme/Jest测试React中经Props设置状态的组件

问题根因

测试不通过的核心原因是被测组件是标准的受控组件:组件本身不持有isShowing状态,状态值完全由父组件通过props注入,状态更新也完全依赖父组件传入的setShow方法。你在测试中传入的setShow是空函数,点击按钮触发后不会对传入的isShowing值做任何修改,isShowing始终为初始的false,自然不会渲染出h1标签。

测试逻辑

这类受控组件的测试不需要覆盖状态本身的流转逻辑(状态管理是父组件的职责),只需要验证两个核心行为:

  • 传入不同props时,组件渲染结果符合预期
  • 触发交互动作时,组件会以正确的参数调用传入的状态更新方法

如果需要验证点击后内容显示的完整交互链路,可以在测试侧模拟父组件的行为:要么用mock函数捕获setShow的调用参数后手动更新组件props,要么写一个轻量包装组件,用真实的React状态管理逻辑对接被测组件。

修正后的测试代码

单元测试写法(隔离验证组件逻辑)

import Enzyme, { mount } from 'enzyme';
import EnzymeAdapter from 'enzyme-adapter-react-16';
// 注意替换为你的组件实际路径
import { Component } from './Component';

Enzyme.configure({ adapter: new EnzymeAdapter() });

describe('Component works as expected', () => {
  test('点击按钮时会传入取反后的状态值调用setShow', () => {
    const mockSetShow = jest.fn();
    const wrapper = mount(<Component isShowing={false} setShow={mockSetShow} />);
    
    wrapper.find('button').simulate('click');
    // 验证调用setShow时传入的参数是!false也就是true
    expect(mockSetShow).toHaveBeenCalledWith(true);
    
    wrapper.unmount();
  });

  test('isShowing为true时渲染Showing文案,为false时不渲染', () => {
    const mockSetShow = jest.fn();
    const wrapper = mount(<Component isShowing={false} setShow={mockSetShow} />);
    // 初始状态下h1不存在
    expect(wrapper.find('h1').exists()).toBe(false);
    
    // 模拟父组件传入更新后的状态
    wrapper.setProps({ isShowing: true });
    expect(wrapper.find('h1').text()).toBe("Showing");
    
    wrapper.unmount();
  });
});

集成测试写法(模拟真实使用场景)

如果要覆盖完整交互流程,可以写一个简单的包装组件模拟父组件的状态管理,不需要手动更新props:

import React, { useState } from 'react';
import Enzyme, { mount } from 'enzyme';
import EnzymeAdapter from 'enzyme-adapter-react-16';
import { Component } from './Component';

Enzyme.configure({ adapter: new EnzymeAdapter() });

describe('Component full interaction', () => {
  test('点击按钮可以正常切换内容显隐', () => {
    // 测试用父组件,持有真实状态
    const TestWrapper = () => {
      const [isShowing, setShow] = useState(false);
      return <Component isShowing={isShowing} setShow={setShow} />;
    };

    const wrapper = mount(<TestWrapper />);
    // 初始状态不显示h1
    expect(wrapper.find('h1').exists()).toBe(false);
    // 第一次点击显示内容
    wrapper.find('button').simulate('click');
    expect(wrapper.find('h1').text()).toBe("Showing");
    // 第二次点击隐藏内容
    wrapper.find('button').simulate('click');
    expect(wrapper.find('h1').exists()).toBe(false);

    wrapper.unmount();
  });
});

注意:如果使用React 17/18版本,需要替换对应版本的enzyme适配器,或者切换为React Testing Library,测试逻辑是一致的。

内容的提问来源于stack exchange,提问作者Pikica

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 01:54:23