title: expect(...).toHaveBeenCalled() fails even though the React component method is called
body: <p>I am attempting to test whether a React component method is called using enzyme and jest. The function is supposed to be called when a <code>&lt;section&gt;</code> element becomes unfocused (on blur). The component is connected to a Redux store, but it is also exported by name, to take Redux out of the equation. Below is a simplified version of the component:</p>
  
  <pre><code>export class Section extends React.Component {
    constructor(props) {
      super(props)
      this.formRef = React.createRef();
      this.submitForm = this.submitForm.bind(this);
      this.state = {
        formSubmitted: false
      }
    }
  
    submitForm() {
      console.log("form submitted");
      this.setState({ formSubmitted: true })
      if (this.formRef &amp;&amp; this.formRef.current) {
        this.formRef.current.submit();
      }
    }
  
    render() {
      return (
        &lt;section onBlur={this.submitForm}&gt;
          &lt;form ref={this.formRef} action={url} method='post'&gt;
            &lt;input type="text" name="something" /&gt;
          &lt;/form&gt;
        &lt;/section&gt;
      );
    }
  }
  
  export default connect(
    mapStateToProps,
    mapDispatchToProps
  )(Section);
  </code></pre>
  
  <p>I have tried all kinds of combinations for the <code>spyOn</code> portion, since it seems to be the root of the issue. All have failed.</p>
  
  <pre><code>import React from 'react';
  import { shallow } from 'enzyme';
  import { Section } from './Section';
  
  describe('Section', () =&gt; {
    it('should submit form on blur', () =&gt; {
      const wrapper = shallow(&lt;Section content={{ body: [] }} /&gt;);
      const spy = spyOn(wrapper.instance(), 'submitForm');
      const spy2 = spyOn(Section.prototype, 'submitForm');
      const spy3 = jest.spyOn(wrapper.instance(), 'submitForm');
      const spy4 = jest.spyOn(Section.prototype, 'submitForm');
  
      wrapper.find('section').simulate('blur');
      expect(wrapper.state().formSubmitted).toEqual(true);
      expect(spy).toHaveBeenCalled();
      expect(spy2).toHaveBeenCalled();
      expect(spy3).toHaveBeenCalled();
      expect(spy4).toHaveBeenCalled();
    })
  })
  </code></pre>
  
  <p>I gave the component a state and tested it in addition to testing <code>expect(...).toHaveBeenCalled</code> in order to verify whether the function was actually called, and it seems to be the case. </p>
  
  <p>The <code>console.log('form submitted')</code> appears in the console.</p>
  
  <p>The test <code>expect(wrapper.state().formSubmitted).toEqual(true);</code> passes, which indicates to me that the correct function is being called. However, I don't want to have an unnecessary state just for the test. The state has just been added to assert that "submitForm" method is being called.</p>
  
  <p>The assertions <code>expect(...).toHaveBeenCalled()</code> all fail with error <code>Expected spy to have been called, but it was not called</code> or <code>Expected mock function to have been called, but it was not called.</code></p>