当前位置: 首页 > 知识库问答 >
问题:

使用酶测试React组件状态的更改并监视实例方法

胡鸿禧
2023-03-14

我正在研究一个包装组件,以便在React中顺利加载图像。我用酶和摩卡、茶和西农一起对我的成分进行单元测试。在这里的测试中,我试图测试:

> < li>

当图像加载时,组件的状态会更新

调用了组件上的 onLoad 实例方法

const wrapper = shallow( );

const onLoad = wrapper.find('img').props().onLoad;
const onLoadSpy = sinon.spy(onLoad); wrapper.update();
const status = wrapper.state().status;
expect(onLoadSpy).to.have.been.called;
expect(status).to.equal('LOADED');

我发现状态的更新既没有被酶反映出来,也没有更新onLoad间谍的调用计数。这是测试的相应代码:

export default class Image extends Component {
  constructor(props) {
    super(props);
    if (props.src != null && typeof props.src === 'string') {
      this.state = {
        status: LOADING,
      };
    } else {
      this.state = {
        status: PENDING,
      };
    }
    this.onLoad = this.onLoad.bind(this);
  }

  onLoad() {
    this.setState({
      status: LOADED,
    });
  }

  render() {
    //lots of code above the part we care about
    const defaultImageStyle = style({
      opacity: 0,
      transisition: 'opacity 150ms ease',
    });

    const loadedImageStyle = style({
      opacity: 1,
    });

    let imageStyle = defaultImageStyle;

    if (this.state.status === LOADED) {
      imageStyle = merge(defaultImageStyle, loadedImageStyle);
    } else {
      imageStyle = defaultImageStyle;
    }


    let image;
    if (alt != null) {
      image = (<img
        className={imageStyle}
        src={src}
        width={width}
        height={height}
        alt={alt}
        onLoad={this.onLoad}
      />);
    } else {
      image = (<img
        className={imageStyle}
        src={src}
        width={width}
        height={height}
        role="presentation"
        onLoad={this.onLoad}
      />);
    }

    let statusIndicator = null;
    if (this.state.status === LOADING) {
      statusIndicator = (<div className={loadingStyle}></div>);
    }

    return (<div className={wrapperStyle}>
      {statusIndicator}
      {image}
    </div>);

    }}

要查看完整代码以获得更好的上下文,请执行以下操作:

>

  • 这里的来源

    这里的测试

  • 共有2个答案

    梁嘉澍
    2023-03-14

    我认为这种方法的主要问题是状态是一种内部的东西,而不是应该在组件之外知道的东西。现在,您正在将状态信息(在本例中为“status”)泄漏到测试中。

    这样做意味着你不是在做“黑盒测试”,这是最有价值的测试类型。您正在泄漏组件的实现细节。换句话说,应该高度重视“封装”。

    也许有更好的方法来测试这一点。例如,您也可以导出一个表示组件,该组件将您需要测试的状态部分作为道具。或者寻找一个元素,当状态为“LOADED”时,用酶查找方法呈现。

    董琦
    2023-03-14

    可以在不依赖sinon的情况下对此进行测试。通过期望调用onLoadonFire事件侦听器,测试检查img是否触发loaderror事件。

    相反,使用enzyme模拟img的事件,并检查是否发生了适当的状态转换:

    it('has a state of LOADED if a good src prop is supplied', () => {
      const wrapper = shallow(<Image 
        src="anyString.jpg"
        width={300}
        height={300}
      />);
    
      const img = wrapper.find('img');
      img.simulate('load');
      const status = wrapper.state().status;
      expect(status).to.equal('LOADED');
    });
    

    这也消除了安装组件的需要。可以在此处找到更新的测试。

     类似资料:
    • 问题内容: 我正在尝试测试React组件的样式属性。在测试中获取样式参数的最佳方法是什么? 目前,我最好的选择是测试HTML是否包含字符串,但是我认为有一个更好的选择。 案件: 要测试的组件是: 问题答案: 您可以使用此方法。它返回ReactElement。

    • 问题内容: 我有两个组件: 父组件 ,我想从中更改子组件的状态: 和 子组件 : 我需要从父组件更改子组件的 打开 状态,还是单击父组件中的按钮时从父组件调用子组件的 toggleMenu() ? 问题答案: 状态应在父组件中进行管理。您可以通过添加属性将值传输到子组件。

    • 问题内容: react:16.3.0-alpha.1 jest: “22.3.0” enzyme: 3.3.0 typescript: 2.7.1 码: 测试: 错误: 问题答案: 解: 1:使用异步/等待语法。 2:使用安装座(不浅)。 3:等待异步组件生命周期。 例如:

    • 我试图使用React Hooks来管理一个简单的文本输入字段和提交输入按钮的状态。输入字段不断验证(现在只是检查长度 我已将参数扩展为setMuffinSettings,以显式返回一个对象,并已确认此返回对象的顺序为:true。因此,问题与setMuffinSettings本身有关,而不是传递给setMuffinSettings的对象不正确。 我还研究了另外两个与React挂钩(特别是挂钩)和“落

    • 问题内容: 所以,我有多个ReactComponent。最初,我以为会有一个带有其自身状态的父组件(简称为GrandPa),它将有关其状态的一些信息传递给另一个组件(称为Parent)。同样,父母将他的一些财产传给孩子,孩子则传给孙子。因此,我们具有层次结构: 爷爷->父母->孩子->孙子 但是,我很快意识到,当我使用method 更改GrandPa的状态时,所做的更改不会沿通道向下级联。我意识到

    • 问题内容: 我正在尝试制作一个不错的ApiWrapper组件,以填充各种子组件中的数据。从我阅读的所有内容来看,这应该可以正常工作:https : //jsfiddle.net/vinniejames/m1mesp6z/1/ 但是由于某种原因,当父状态更改时,子组件似乎没有更新。 我在这里想念什么吗? 问题答案: 您的代码有两个问题。 您的子组件的初始状态是通过props设置的。 引用此SO答案: