Enzyme: Stateless functional components support

Created on 12 Apr 2016  路  15Comments  路  Source: enzymejs/enzyme

Hi!

I am trying to test the following SFC:

import React from 'react';

const Icon = ({ name }) => {
  switch (name) {
    case 'airport': return <i className="material-icons">&#xE195;</i>;
    case 'place': return <i className="material-icons">&#xE0C8;</i>;
    default: return '';
  }
};

export default Icon;

With the following test:

import React from 'react';
import Icon from 'app/components/base/Icon';

describe('<Icon />', () => {
  it('Should not render if a name is not provided', () => {
    const component = enzyme.shallow(<Icon />);
  });
});

Getting the following error:

1) <Icon /> Should not render if a name is not provided:
     TypeError: inst.render is not a function
      at [object Object].ReactCompositeComponentMixin._renderValidatedComponentWithoutOwnerOrContext (node_modules/react/lib/ReactCompositeComponent.js:587:34)
      at [object Object].ReactCompositeComponentMixin.mountComponent (node_modules/react/lib/ReactCompositeComponent.js:220:30)
      at [object Object].wrapper [as mountComponent] (node_modules/react/lib/ReactPerf.js:66:21)
      at [object Object].ReactShallowRenderer._render (node_modules/react/lib/ReactTestUtils.js:366:14)
      at _batchedRender (node_modules/react/lib/ReactTestUtils.js:348:12)
      at ReactDefaultBatchingStrategyTransaction.Mixin.perform (node_modules/react/lib/Transaction.js:136:20)
      at Object.ReactDefaultBatchingStrategy.batchedUpdates (node_modules/react/lib/ReactDefaultBatchingStrategy.js:62:19)
      at Object.batchedUpdates (node_modules/react/lib/ReactUpdates.js:94:20)
      at [object Object].ReactShallowRenderer.render (node_modules/react/lib/ReactTestUtils.js:343:16)
      at [object Object].render (node_modules/enzyme/build/react-compat.js:146:39)
      at new ShallowWrapper (node_modules/enzyme/build/ShallowWrapper.js:81:21)
      at Object.shallow (node_modules/enzyme/build/shallow.js:21:10)
      at Context.<anonymous> (build/tests/unit/components/base/Icon.test.js:8:30)

Most helpful comment

@Aweary Sorry for providing incorrect information. The problem isn't caused by enzyme, but by the auto-mocking of jest. An auto mocked Stateless Functional Component returns undefined and this isn't allowed by React (you should return null (or a valid React element). Not sure how I can 'fix' this, because explicitly mocking all Stateless Functional Components is quite a burden.

All 15 comments

Can you confirm which version of React you're using? The error message implies 0.13, which doesn't support SFCs.

Sorry:
React version: 0.14.1
Enzyme: 2.2.0

@montogeek did you find a solution for mounting stateless functional components, because they don't work for me using Enzyme 2.2.0 together with React 0.14.1 (nor does it work with React 15.0.1).

I now use the workaround I found at https://github.com/airbnb/enzyme/issues/45#issue-120431294 but this defeats the purpose of using stateless components...

@nvdbleek No, I thought it was a problem with React 0.14.1, never fixed it.
(Un)fortunately component implementation changed.

Have you tried returning null with React 15?

As a note, React 15 is fully supported according to @ljharb https://gitter.im/airbnb/enzyme?at=571aa7269689a5440f7ab469

@montogeek I believe the issue with your original snippet is that you're returning a string as the default case. This isn't supported, even by React 15.0.1: https://jsfiddle.net/v14jn1tk/

I've verified that the current master branch of enzyme runs this test fine with React 15:

it('Should not render if a name is not provided', () => {
      const Icon = ({ name }) => {
        switch (name) {
          case 'airport': return <div>{name}</div>;
          case 'place': return <h2>{name}</h2>;
          default: return null;
        }
      };
      shallow(<Icon />);
    });

If you return a string from a stateless component with React 15 you get a more helpful error when running your test:

Invariant Violation: Icon(...): A valid React element (or null) must be returned.
You may have returned undefined, an array or some other invalid object.

@Aweary Yep :D
Hopefully @nvdbleek could find this as a solution :)

I hope that this is the problem, but I don't think that we return a string in the stateless components where we have the problem, but I'll check.

@nvdbleek if you are having a separate issue, I'd appreciate if you could share the code snippet causing your error!

@Aweary I will try to create a small test case, the problem happens in some big components, and as I saw this issue I didn't took the time to create a small test-case yet.

@Aweary Sorry for providing incorrect information. The problem isn't caused by enzyme, but by the auto-mocking of jest. An auto mocked Stateless Functional Component returns undefined and this isn't allowed by React (you should return null (or a valid React element). Not sure how I can 'fix' this, because explicitly mocking all Stateless Functional Components is quite a burden.

@nvdbleek if you have a reproducable case showing that SFCs return undefined when mock'd I'd open an issue over at facebook/jest and see what they say.

@Aweary it isn't a 'bug' in jest in my opinion. All auto-mocked functions return undefined, if you want them to return something else you have to manually mock them, of override the return value. But this is of course not funny, because now you need to know in your tests which SFC-components are used in the implementation of the class that you are testing, and you need to manually mock them...

I wouldn't say it's a bug, I'm just curious if jest could recognize when it's mocking a React component and handle that accordingly, or if there would be a way to declare a custom global return value for all (or a set of)mock'd functions. I'm not super familiar with jest though, so IDK what that would involve.

Anyways, if there's no reproducable case of enzyme failing with SFCs, this issue should probably be closed @ljharb

I'm asking the question to cpojer on th Discord jest channel. If I get an answer, I'll update this github issue

We just merged https://github.com/airbnb/enzyme/pull/394 which added lots of tests for SFCs. Since there doesn't seem to be an actual issue here I'm going to close this out

Was this page helpful?
0 / 5 - 0 ratings