Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to assert a function is called from within another function?

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();
  });
}
like image 462
blueyodeler Avatar asked Jul 14 '17 12:07

blueyodeler


People also ask

Can you call a function from another function?

It is important to understand that each of the functions we write can be used and called from other functions we write. This is one of the most important ways that computer scientists take a large problem and break it down into a group of smaller problems.

Can you use a function inside another function python?

A function defined inside another function is called a nested function. Nested functions can access variables of the enclosing scope. In Python, these non-local variables are read-only by default and we must declare them explicitly as non-local (using nonlocal keyword) in order to modify them.

How do you test a function has been called in jest?

How to check if a function was called correctly with Jest? To check if a function was called correctly with Jest we use the expect() function with specific matcher methods to create an assertion. We can use the toHaveBeenCalledWith() matcher method to assert the arguments the mocked function has been called with.

What is assert Isinstance?

The assertIsInstance() is a method of the TestCase class of the unittest module. The assertIsInstance() method tests if an object is an instance of a class.


1 Answers

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 :)

like image 124
Hardik Modha Avatar answered Oct 14 '22 23:10

Hardik Modha