geo
geo

Reputation: 2433

How can I test an internal method inside a component in React?

I am trying to test spy a method used inside a React component but I am failing. The component is the below :

export class SiderMenu extends PureComponent {

formatter(data, parentPath = '', parentAuthority) {
  return data.map((item) => {
  const result = {
    ...item,
    path: `${parentPath}${item.path}`,
  };
  return result;
});
}
constructor(props) {
  super(props);
  this.menus = this.formatter(props.menuData);
}
render(....)
}

I am using enzyme and I want to test that the formatter method has been called:

describe.only('SiderMenu.formatter', () => {
  it('Expect to have been called', () => {
  // const spy = jest.spyOn(SiderMenu.prototype, 'formatter');
  const wrapper = shallow(<SiderMenu />);
  const instance = wrapper.instance();
  const method = jest.spyOn(instance, 'formatter');
  expect(method).toHaveBeenCalled();
  });
 });

I tried also to spy the method using the prototype of the component but I constantly taking the below error

TypeError: Cannot read property '_isMockFunction' of undefined

This error is created by the 'jest.spyOn(instance, 'formatter');'. Can someone help me out about this ? How can I test that formatter method has been called ?

Upvotes: 1

Views: 2499

Answers (2)

Rob Wise
Rob Wise

Reputation: 5120

The following works perfectly fine for me:

describe.only('SiderMenu.formatter', () => {
  it('Expect to have been called', () => {
    const spy = jest.spyOn(SiderMenu.prototype, 'formatter');
    const wrapper = shallow(<SiderMenu menuData={[{ path: 'foo' }]} />);
    const instance = wrapper.instance();

    expect(spy).toHaveBeenCalled();
  });
});

Make sure you are passing some menuData so that the component doesn't blow up when it tries to map over undefined. There are some gotchas with getting this to work (such as using class properties), but you've avoided them here. For more info, see this GitHub issue.

Upvotes: 2

Krasimir
Krasimir

Reputation: 13529

I know nothing about your app but aren't you interested in what formatter does or what's the output of it. Why not run an expectation on this.menus just after creating an instance of SiderMenu.

Upvotes: 0

Related Questions