最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to assert a function is called from within another function? - Stack Overflow

programmeradmin4浏览0评论

I have a component in React with an onChange event. In the code below, I need to assert that the correct method is called when

this.props.onChangeImage()

is invoked in the Gallery component.

export class Form extends React.PureComponent {

  componentDidMount = () => {
    this.props.getUser();
    this.props.getImages();
    this.props.getBoards();
  }

  render() {
    if (this.props.pin === null) {
      let boards = [];
      boards = this.props.boards;
      boards = boards.data.map(
        (item) => <MenuItem key={item.id.toString()} value={item.name} primaryText={item.name} />
      );
      return (
        <div>
          <Helmet
            title="Form"
            meta={[
              { name: 'description', content: 'Description of Form' },
            ]}
          />
          <Gallery images={this.props.images} onChange={this.props.onChangeImage} />
        </div>
      );
    }
    return (<div className="spinner-container"><CircularProgress /></div>);
  }
}

Below, in the onChangeImage method, I am trying to assert that the sendEventToParentWindow method is called.

function mapDispatchToProps(dispatch) {
  return {

    onChangeImage: (event) => {
      dispatch(createPinImage(event.target.value));
      sendEventToParentWindow({
        action: 'change-image',
        description: 'Change image',
      });
    },
  };
}

function sendEventToParentWindow(message) {
  window.postMessage(message, window.location.href);
}

export default connect(mapStateToProps, mapDispatchToProps)(Form);

I've looked at a number of answers here, and while this one seemed closest, it's not quite getting me there: Jest - mocking a function call

EDIT: Here is my test which I believe is wrong because it's assigning the mocked function to be called directly onChange when it really should be calling the function that in turn calls the mock. I need somehow to invoke the onImageChange function and then verify that my spy was called.

import Gallery from '../index';
import * as formIndex from '../../../containers/Form';

describe('<Gallery />', () => {
  it('Expect sendMessageToParentWindow to be called on image change', () => {
    const sendEventToParentWindowMock = jest.spyOn(formIndex, 'sendEventToParentWindow');
    const gallery = shallow(<Gallery images={imagesMockData} onChange={sendEventToParentWindowMock} />);
    gallery.find('input#image-1').simulate('change');

    expect(sendEventToParentWindowMock).toBeCalled();
  });
}

I have a component in React with an onChange event. In the code below, I need to assert that the correct method is called when

this.props.onChangeImage()

is invoked in the Gallery component.

export class Form extends React.PureComponent {

  componentDidMount = () => {
    this.props.getUser();
    this.props.getImages();
    this.props.getBoards();
  }

  render() {
    if (this.props.pin === null) {
      let boards = [];
      boards = this.props.boards;
      boards = boards.data.map(
        (item) => <MenuItem key={item.id.toString()} value={item.name} primaryText={item.name} />
      );
      return (
        <div>
          <Helmet
            title="Form"
            meta={[
              { name: 'description', content: 'Description of Form' },
            ]}
          />
          <Gallery images={this.props.images} onChange={this.props.onChangeImage} />
        </div>
      );
    }
    return (<div className="spinner-container"><CircularProgress /></div>);
  }
}

Below, in the onChangeImage method, I am trying to assert that the sendEventToParentWindow method is called.

function mapDispatchToProps(dispatch) {
  return {

    onChangeImage: (event) => {
      dispatch(createPinImage(event.target.value));
      sendEventToParentWindow({
        action: 'change-image',
        description: 'Change image',
      });
    },
  };
}

function sendEventToParentWindow(message) {
  window.postMessage(message, window.location.href);
}

export default connect(mapStateToProps, mapDispatchToProps)(Form);

I've looked at a number of answers here, and while this one seemed closest, it's not quite getting me there: Jest - mocking a function call

EDIT: Here is my test which I believe is wrong because it's assigning the mocked function to be called directly onChange when it really should be calling the function that in turn calls the mock. I need somehow to invoke the onImageChange function and then verify that my spy was called.

import Gallery from '../index';
import * as formIndex from '../../../containers/Form';

describe('<Gallery />', () => {
  it('Expect sendMessageToParentWindow to be called on image change', () => {
    const sendEventToParentWindowMock = jest.spyOn(formIndex, 'sendEventToParentWindow');
    const gallery = shallow(<Gallery images={imagesMockData} onChange={sendEventToParentWindowMock} />);
    gallery.find('input#image-1').simulate('change');

    expect(sendEventToParentWindowMock).toBeCalled();
  });
}
Share Improve this question edited Aug 11, 2020 at 12:48 Flip 6,7618 gold badges50 silver badges83 bronze badges asked Jul 14, 2017 at 12:23 blueyodelerblueyodeler 1331 gold badge2 silver badges7 bronze badges 6
  • Which testing library are you using? Enzyme? If yes then are you shallow rendering the component? – Hardik Modha Commented Jul 14, 2017 at 13:11
  • @HardikModha, I do have Enzyme available to me and have tried shallow rendering and mounting the component. I didn't have any luck, but I am still learning and tinkering. Thanks for the tip! – blueyodeler Commented Jul 14, 2017 at 13:17
  • 1 You can pass the mocked function (whose implementation contains a mock method call) as prop when you are shallow rendering the component. – Hardik Modha Commented Jul 14, 2017 at 13:19
  • @HardikModha That seems to have done the trick. I was really close to the problem but just hadn't quite made it. Thank you! I'm build some tests with some other components and will repot back if I have any other questions. If all goes well, I'll post my answer. Thanks again! – blueyodeler Commented Jul 14, 2017 at 13:47
  • Glad it helped you. :) – Hardik Modha Commented Jul 14, 2017 at 13:57
 |  Show 1 more comment

1 Answer 1

Reset to default 17

As I mentioned in the comment, You can pass a mocked function as prop whose implementation will contain a call to your sendEventToParentWindow function. i.e. You'll need to create two mocked function.

  1. sendEventToParentWindow mock function.
  2. onChangeImage mock function with implementation, where implementation will only contain call to your sendEventToParentWindow mock function.

So the test will look something like this,

describe('<Gallery />', () => {
  it('Expect sendMessageToParentWindow to be called on image change', () => {
    const sendEventToParentWindowMock = jest.fn();
    const onChangeImageMock = jest.fn(() => {
         sendEventToParentWindowMock();
    });

    const gallery = shallow(<Gallery images={imagesMockData} onChange={onChangeImageMock} />); // Passing the mocked onChangeImage as prop
    gallery.find('input#image-1').simulate('change');

    expect(sendEventToParentWindowMock).toBeCalled();
  });
}

Hope it helps :)

发布评论

评论列表(0)

  1. 暂无评论