title: How to unit test a custom table cell renderer function using react, jest and enzyme?
body: <p>I wanted to test a React class component function that returns JSX content.   Below is my code:   </p>
  
  <p><strong>Products</strong> component</p>
  
  <pre><code>export default class Products extends React.Component {
    constructor(props) {
      super(props);
  
      this.state = {
        products: [],
      };
    }
  
    iconRenderer = (data) =&gt; {
      return (
        &lt;i
          className="fa fa-qrcode fa-3x"
        &gt;
        &lt;/i&gt;
      );
    };
  
    getDisplayColumns = () =&gt; {
      return [
        {
          fieldName: 'producticon',
          displayText: 'Name',
          isEditable: false,
          visible: true,
          columnSize: 2,
          renderer: this.iconRenderer
        }
      ];
    };
  
    render() {
      const displayColumns = this.getDisplayColumns();
      return (
        &lt;div className=''&gt;
              {this.state.products &amp;&amp; this.state.products.length &gt; 0 &amp;&amp;
              &lt;CustomTableGeneric
                tableId="item-list-table"
                data={this.state.products}
                columns={displayColumns}
              &gt;
              &lt;/CustomTableGeneric&gt;
              }
            &lt;/div&gt;
      );
    }
  }
  </code></pre>
  
  <p><strong>CustomTableGeneric</strong> component (I tried to simplify the code)   </p>
  
  <pre><code>export default class CustomTableGeneric extends React.Component {
      constructor(props) {
          super(props);
  
          this.state = {
              currentTableData: [],
              columnsToDisplay: [],
          };
  
          this.renderRows = this.renderRows.bind(this);
          this.renderIndividualRow = this.renderIndividualRow.bind(this);
      }
  
      renderIndividualRow(data, dataKeys) {
          return dataKeys.map((item, index) =&gt; {
              let currentRowId = data['id'];
              let columnWidth = this.state.columnsToDisplay[index].columnSize;
              if (item.renderer) {
                      return (
                          &lt;Col md={columnWidth} className="table-column-cell"
                               key={index}&gt;
                              {item.renderer(data, item.fieldName)}
                          &lt;/Col&gt;
                      );
                  } else {
                      return (
                          &lt;Col md={columnWidth} className="table-column-cell" key={index}&gt;{data[item.fieldName]}&lt;/Col&gt;
                      );
                  }
          });
      }
  
      renderRows() {
          let dataKeys = clonedeep(this.state.columnsToDisplay);
          let dataRows = clonedeep(this.state.currentTableData);
          if (dataRows.length &gt; 0) {
              return dataRows.map((row, index) =&gt; {
                  return (
                          &lt;Row key={index} className="table-row"&gt;
                              {this.renderIndividualRow(row, dataKeys)}
                          &lt;/Row&gt;
                      );
              });
          }
      }
  
      render() {
          return (
              &lt;Row id={this.props.tableId}&gt;
                  &lt;Col className="custom-table"&gt;
                      &lt;Row className="table-header"&gt;
                          {this.renderHeaders()}
                      &lt;/Row&gt;
                      {this.renderRows()}
                  &lt;/Col&gt;
              &lt;/Row&gt;
          );
      }
  }
  
  CustomTableGeneric.propTypes = {
      tableId: PropTypes.string,
      data: PropTypes.arrayOf(PropTypes.object).isRequired,
      columns: PropTypes.arrayOf(PropTypes.shape({
          fieldName: PropTypes.string,
          displayText: PropTypes.string,
          renderer: PropTypes.func,
      })).isRequired,
  };
  </code></pre>
  
  <p><strong>Products.test.js</strong>     </p>
  
  <pre><code>import React from 'react';
  import {shallow, mount} from 'enzyme';
  
  import CustomTableGeneric from '../../components/CustomTableGeneric';
  import Products from './Products';
  
  const props = {
    id: '123'
  };
  
  describe('Products function tests', () =&gt; {
    it('should call the iconRenderer function', () =&gt; {
      const wrapper = shallow(&lt;Products {...props} /&gt;);
      const result = wrapper
          .instance()
          .iconRenderer();
      console.log(result);
  
    });
  });
  
  </code></pre>
  
  <p>and below is the console output when I am running the test.    </p>
  
  <pre><code>{ '$$typeof': Symbol(react.element),
        type: 'i',
        key: null,
        ref: null,
        props: { className: 'fa fa-qrcode fa-3x' },
        _owner: null,
        _store: {} }
  </code></pre>
  
  <p>As you can see, if I call <strong>iconRenderer()</strong> explicitly from the test, it is executing. But what I am trying to test is to check whether <strong>iconRenderer()</strong> is getting called when the <strong>Products</strong> component is rendered. Please see how I am calling it inside <strong>render</strong> function, e.g. Products render() -> getDisplayColumns() -> CustomTableGeneric() -> iconRenderer().    </p>
  
  <p>Below is the actual test that I want to run    </p>
  
  <pre><code>describe('Products function tests', () =&gt; {
    it('should call the iconRenderer function', () =&gt; {
      const wrapper = shallow(&lt;Products {...props} /&gt;);
      jest.spyOn(wrapper.instance(), 'iconRenderer');
      expect(wrapper.instance().iconRenderer()).toHaveBeenCalled();
    });
  });
  
  </code></pre>
  
  <p>but I am getting below error    </p>
  
  <pre><code>Error: expect(jest.fn())[.not].toHaveBeenCalled()
  
  jest.fn() value must be a mock function or spy.
  Received:
    object: &lt;i className="fa fa-qrcode fa-3x" /&gt;
  </code></pre>
  
  <p>Any suggestion is highly appreciated.</p>