React: Test fails when render method is NOT an arrow function

Created on 9 Jul 2018  路  13Comments  路  Source: facebook/react

Versions

react: 16.4.1
react-test-renderer: 16.4.1
@babel/core: ^7.0.0-beta.52
babel-jest": "^23.2.0,

Getting TypeError: this._instance.render is not a function if running a test on a component that isn't using an arrow function for the render method

Fails

import React, { Component } from 'react';
import { Text } from 'react-native';
import ShallowRenderer from 'react-test-renderer/shallow';

class TestComponent extends Component {
    render() {
        return <Text>Hello</Text>;
    }
}

describe('ConsultMessages', () => {
    let props;
    let renderer;
    const render = () => {
        if (! renderer) {
            renderer = new ShallowRenderer();
            renderer.render(<TestComponent {...props} />);
        }
        return renderer;
    };

    it('renders without crashing', () => {
        const rendered = render().getRenderOutput();
        expect(rendered).toBeTruthy();
    });
});

Passes

import React, { Component } from 'react';
import { Text } from 'react-native';
import ShallowRenderer from 'react-test-renderer/shallow';

class TestComponent extends Component {
    render = () => <Text>Hello</Text>
}

describe('ConsultMessages', () => {
    let props;
    let renderer;
    const render = () => {
        if (! renderer) {
            renderer = new ShallowRenderer();
            renderer.render(<TestComponent {...props} />);
        }
        return renderer;
    };

    it('renders without crashing', () => {
        const rendered = render().getRenderOutput();
        expect(rendered).toBeTruthy();
    });
});

Reproducible repo

Link here

Needs More Information

Most helpful comment

I looked at the reproducing example in https://github.com/getmaple/TestApp56 again.
I was able to fix it by running:

  • yarn remove @babel/core
  • yarn test --no-cache

In particular, the issue was that the project mistakingly pulled in @babel/core@^7.0.0-beta.52 which is incompatible with React Native 0.56 (which uses @babel/[email protected]). The fix was to remove the unnecessary (and wrong) top-level @babel/core dependency.

Check your package.json for @babel/core. If you see it there, remove it. Or at least ensure it's the same version that Metro depends on. Make sure that in your yarn.lock you don't see two @babel/core with different versions.

Hope this helps!

All 13 comments

The code in the two examples is identical

@jfo84 The render method on the class are different; https://www.diffchecker.com/nryPAwTV

Ah I see. If it's not related to this then I'm not sure

@jfo84 It works fine if I use arrow functions. Doesn't that mean babel-plugin-transform-class-properties is working.

I only get the error when running tests. The app runs fine otherwise.

No `render` method found on the returned component instance: you may have forgotten to define `render`.

@fhadsheikh could you create a repo that we can clone to reproduce the issue? Setting up a repo with all the same dependencies is time consuming for us, so we'll be able to help you quicker if we don't have to 馃檪

In the meantime can you share your react-native version and the full stack trace of the error?

Hi @aweary! I've added the RN version, stack trace and a link to a repo to reproduce bug to the issue

thanks for your help!

Whatever the issue is, it likely isn't React. When the shallow renderer's render method receives the element, initializing it with new here returns an instance without a render method defined.

It could be a createElement issue but I don't see anything. Maybe someone more experienced can chime in.

Hi, I'm running a react-native project and after doing all the babel 7 upgrades after updating react-native to 0.56 I've run into the same issue as @aweary.
I just tried converting the component of one of my failing tests' render method to an arrow function as he suggested and it fixed the issue. This won't be a long term solution though... 馃槶

Also just discovered this issue occurs for stateless functional components too i.e.
const MyComp = () => <Text>Hello Doggy</Text>

Also running into this issue on a react native project, but not when running on iOS or Android, but rather when running on web using react-native-web

This may be related to babel/babel#8392

This is not a React issue.

I see that removing babel-jest from dependencies, and then removing jest configuration section and babel.config.js fixes it. So this must be either a Jest or a Babel issue.

Most likely the advice in https://github.com/babel/babel/issues/8392#issuecomment-408263920 will be relevant to you.

I looked at the reproducing example in https://github.com/getmaple/TestApp56 again.
I was able to fix it by running:

  • yarn remove @babel/core
  • yarn test --no-cache

In particular, the issue was that the project mistakingly pulled in @babel/core@^7.0.0-beta.52 which is incompatible with React Native 0.56 (which uses @babel/[email protected]). The fix was to remove the unnecessary (and wrong) top-level @babel/core dependency.

Check your package.json for @babel/core. If you see it there, remove it. Or at least ensure it's the same version that Metro depends on. Make sure that in your yarn.lock you don't see two @babel/core with different versions.

Hope this helps!

@gaearon i'm also facing the same issue after updating all the babel, jest & react-native dependencies

Error :

    TypeError: this._instance.render is not a function

      17 |
      18 | it('renders correctly', () => {
    > 19 |   const wrapper = shallow(
         |                   ^
      20 |     <MainApp store={store}/>)
      21 |     //expect(wrapper).toMatchSnapshot();
      22 | });

      at ReactShallowRenderer._mountClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:898:41)
      at ReactShallowRenderer.createElement [as render] (node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:815:18)
      at node_modules/enzyme-adapter-react-16/src/ReactSixteenAdapter.js:780:18
      at withSetStateAllowed (node_modules/enzyme-adapter-utils/build/Utils.js:200:16)
      at Object.render (node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:968:68)
      at new ShallowWrapper (node_modules/enzyme/src/ShallowWrapper.js:488:5)
      at shallow (node_modules/enzyme/build/shallow.js:26:10)
      at Object.<anonymous> (__tests__/App.js:19:19)

Version :

enzyme : 3.10.0
enzyme-adapter-react-16 : 1.15.0
react-native : 0.61.4
jest : 24.7.1
babel-jest : 24.9.0
react:16.9.0
react-dom : 16.9.0
react-test-renderer : 16.9.0
Was this page helpful?
0 / 5 - 0 ratings