首页 > 解决方案 > 如何在 FileReader.onload 中使用 toHaveBeenCalled()

问题描述

我有加载图像并通过 props.handle 函数将图像数据发送到父组件的组件我如何在 fileReader.onload 中模拟或调用 props.handle 也许需要使用异步,但我不知道如何。

尝试重复这个问题的代码How do I test `image.onload` using jest in the context of redux actions(或其他在操作中分配的回调) 但它没有帮助

ChildComponent.js:

class ChildComponent extends React.PureComponent {
  constructor(props) {
    super(props);
  }

  handleFileLoad = event => {
    event.preventDefault();

    const reader = new FileReader();

    reader.onload = () => {
      const data = reader.result;
      this.props.parentHandleFunction(data)
    }
    reader.readAsDataURL(event.target.files[0]);
  }
}

ChildComponent.propTypes = {
  parentHandleFunction: PropTypes.func.isRequired,
};

ChildComponent.test.js:

describe('<ChildComponent />', () => {
    let renderComponent;
    let changeSpy;
    beforeEach(() => {
     changeSpy = jest.fn(value => value);

    renderComponent = shallow(
      <ChildComponent parentHandleFunction={changeSpy}/>,
    );
  });
    it('should call handle file change', () => {
    const childComponent = shallow(
      renderComponent.find(ChildComponent).getElement(),
    );
    const file = new Blob(['image'], { type: 'image/jpeg' });

    loadButton.find('input').simulate('change', {
      preventDefault: () => {},
      target: {
        files: [file],
      },
    });

    expect(changeSpy).toHaveBeenCalled();
  });
})

测试显示错误:“预期的模拟函数已被调用,但未被调用。”

更新

我通过在单独的函数中削减 onload 逻辑来解决我的问题


## ChildComponent.js  ##
class ChildComponent extends React.PureComponent {
  constructor(props) {
    super(props);
  }

  loadImage = data => {
    const imageObject = {
      url: data,
    };

    this.props.parentHandleFunction(
      imageObject,
    );
  }
  handleFileLoad = event => {
    event.preventDefault();
    const reader = new FileReader();
    reader.onload = async () => this.loadImage(reader.result);
    reader.readAsDataURL(event.target.files[0]);
  }
}

ChildComponent.propTypes = {
  parentHandleFunction: PropTypes.func.isRequired,
};

ChildComponent.test.js:

it('should call change spy function', () => {
   renderComponent.instance().loadImage('mockImage');

    renderComponent.update();
    renderComponent.instance().forceUpdate(); 
    expect(changeSpy).toHaveBeenCalled();
  });

标签: reactjsenzyme

解决方案


推荐阅读