title: React test - how to test functions inside jsx rendered with render props
body: <p>I would like to test the content of the jsx that gets rendered with render prop. I use <strong>react-test-renderer</strong> for testing.</p>
  <p>This is the <code>Menu</code> component that has a render prop which I would like to test:</p>
  <pre><code>   &lt;Menu
        menuItems={createMenuItems(cities, onOpenCity)}
        render={(openMenu, onClick, children) =&gt; (
          &lt;&gt;
            &lt;Button
              buttonRef={node =&gt; this.anchorEl = node}
              onClick={onClick}
              className={`${classes.iconWrapper} ${classes.marginIcons} ${openMenu &amp;&amp; classes.active}`}
              &lt;Book fill={openMenu ? '#000' : '#fff'}/&gt;
            &lt;/Button&gt;
            {children(this.anchorEl)}
          &lt;/&gt;
        )}
      &gt;
      &lt;/Menu&gt;
  </code></pre>
  <p>The Menu component looks like this:</p>
  <pre><code>class Menu extends React.Component {
    static propTypes = {
      menuItems: PropTypes.arrayOf(PropTypes.shape({text: PropTypes.string, defaultAction: PropTypes.object})).isRequired
    };
  
    state = {
      openMenu: false,
    };
  
    onToggleMenu() {
      this.setState(prevState =&gt; ({openMenu: !prevState.openMenu}))
    }
  
    onCloseMenu() {
      this.setState({openMenu: false})
    }
  
    render() {
      const {openMenu} = this.state;
      const {classes, render, menuItems} = this.props;
  
      return render(
        openMenu,
        () =&gt; this.onToggleMenu(),
        (anchorEl) =&gt; (&lt;Popper open={openMenu} anchorEl={anchorEl} placement=&quot;bottom-end&quot; transition
                               disablePortal&gt;
            {({TransitionProps, placement}) =&gt; (
              &lt;Grow
                {...TransitionProps}
                id=&quot;menu-list-grow&quot;
                style={{transformOrigin: placement === 'bottom' ? 'center top' : 'center bottom'}}
              &gt;
                &lt;Paper&gt;
                  &lt;ClickAwayListener onClickAway={() =&gt; this.onCloseMenu()}&gt;
                    &lt;MenuList disablePadding&gt;
                      {menuItems.map(menuItem =&gt; (
                        &lt;MenuItem
                          key={menuItem.text}
                          className={classes.menuItem}
                          onClick={() =&gt; {
                            menuItem.action();
                            this.onCloseMenu();
                          }}&gt;{menuItem.text}&lt;/MenuItem&gt;
                      ))}
                    &lt;/MenuList&gt;
                  &lt;/ClickAwayListener&gt;
                &lt;/Paper&gt;
              &lt;/Grow&gt;
            )}
          &lt;/Popper&gt;
        ))
    }
  }
  </code></pre>
  <p>I am trying to write some tests for this component:</p>
  <pre><code>describe('Menu', () =&gt; {
    const context = setupTeardownWithTestRenderer();
    const menuItems = [
      {
        text: '1st item',
        action: () =&gt; {}
      }
    ];
    const renderFunction = (openMenu, onClick, children) =&gt; children(&lt;Button onClick={onClick}&gt;Menu&lt;/Button&gt;);
  
    function renderMenu() {
      const WithRootMenu = withRoot(Menu);
      const testRenderer = context.render(&lt;WithRootMenu menuItems={menuItems} render={renderFunction}/&gt;);
      return testRenderer.root.findByType(Menu.Naked);
    }
  
    it('renders menu', () =&gt; {
      const menu = renderMenu();
      expect(menu.instance.state.openMenu).toBeFalsy();
      const menuList = menu.findByType(MenuList);
      console.log(menuList);
    });
  });
  </code></pre>
  <p>I am trying to get the <code>MenuList</code> since I would like to test the functions on <code>onClick</code> prop of <code>MenuItem</code> component.
  I am setting up test with <code>setupTeardownWithTestRenderer</code> function:</p>
  <pre><code>export function setupTeardownWithTestRenderer() {
    const context = new SimpleTestContext();
    context.setupBeforeAfter();
    return context;
  }
  </code></pre>
  <p>The SimpleTestContext is a class that has some helper methods for setting up tests:</p>
  <pre><code>class SimpleTestContext {
    defaultNodeMock = {
      createNodeMock: (element) =&gt; {
        if (element.type === 'input') {
          // return document.createElement('input');
          //console.log('createNodeMock got input', element.props);
        }
        if (element.type === 'textarea') {
          // console.log('createNodeMock got textarea', element.props);
          return document.createElement('textarea');
        }
        return null;
      }
    };
  
    testRenderer = {unmount: () =&gt; {}}; // null object
  
    setup() {
      this.consoleErrorSpy = jest.spyOn(global.console, 'error');
      this.consoleErrorSpy.mockReset();
      Document.prototype.exitFullscreen = jest.fn();
      jest.useFakeTimers();
    }
  
    tearDown() {
      this.testRenderer.unmount();
      jest.runAllTimers();
      jest.useRealTimers();
      expect(this.consoleErrorSpy).not.toHaveBeenCalled();
    }
  
    act(func)  {
      TestRenderer.act(func);
    }
  
    render(jsx, options) {
      this.testRenderer = TestRenderer.create(jsx, options);
      return this.testRenderer;
    }
  
    renderWithDefaultNodeMock(jsx) {
      return this.render(jsx, this.defaultNodeMock);
    }
  
    async waitForComponent(component) {
      await waitForExpect(() =&gt; expect(
        this.testRenderer.root.findAllByType(component)
          .map(instance =&gt; ({ props: instance.props, type: instance.type }))).toHaveLength(1));
      return this.testRenderer.root.findByType(component);
    }
  
    async waitForComponentByProps(props) {
      await waitForExpect(() =&gt; expect(
        this.testRenderer.root.findAllByProps(props)
          .map(instance =&gt; ({props: instance.props, type: instance.type}))).toHaveLength(1));
      return this.testRenderer.root.findByProps(props);
    }
  
    async waitForComponentToLoad(component) {
      const instance = await this.waitForComponent(component);
      await waitForExpect(() =&gt; expect(instance.instance.state.hasLoaded).toBeTruthy());
      return instance;
    }
  
    setupBeforeAfter() {
      beforeEach(() =&gt; {
        this.setup();
      });
      afterEach(() =&gt; {
        this.tearDown();
      });
    }
  }
  </code></pre>
  <p>My problem is that if I run the test where I try to find MenuList for example:</p>
  <pre><code>  it('renders menu', () =&gt; {
      const menu = renderMenu();
      console.log(menu.instance);
      const menuList = menu.findByType(MenuList);
      console.log(menuList);
    });
  </code></pre>
  <p>I get an error:</p>
  <blockquote>
  <p>Error: No instances found with node type: &quot;undefined&quot;</p>
  </blockquote>
  <p>How can I test what gets rendered with components that use render prop to render jsx?</p>