How use toHaveBeenCalled() inside FileReader.onload

Viewed 495

I have component that load image and send image data up to parent component via props.handle function How I can mock or call props.handle inside fileReader.onload Maybe need use async, but I don't know how.

Was try repeat code from this question How do I test `image.onload` using jest in the context of redux actions (or other callbacks assigned in the action) But it didn't help

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();
  });
})

Tests show errror: 'Expected mock function to have been called, but it was not called.'

update

I solve my problem by cuting onload logic in seprate function


## 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();
  });
0 Answers
Related