Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stateless functional components support #319

Closed
montogeek opened this issue Apr 12, 2016 · 15 comments
Closed

Stateless functional components support #319

montogeek opened this issue Apr 12, 2016 · 15 comments

Comments

@montogeek
Copy link

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)
@ljharb
Copy link
Member

ljharb commented Apr 12, 2016

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

@montogeek
Copy link
Author

Sorry:
React version: 0.14.1
Enzyme: 2.2.0

@nvdbleek
Copy link

@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 #45 (comment) but this defeats the purpose of using stateless components...

@montogeek
Copy link
Author

montogeek commented Apr 28, 2016

@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

@aweary
Copy link
Collaborator

aweary commented Apr 28, 2016

@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.

@montogeek
Copy link
Author

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

@nvdbleek
Copy link

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.

@aweary
Copy link
Collaborator

aweary commented Apr 28, 2016

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

@nvdbleek
Copy link

@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.

@nvdbleek
Copy link

@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.

@aweary
Copy link
Collaborator

aweary commented Apr 29, 2016

@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.

@nvdbleek
Copy link

@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...

@aweary
Copy link
Collaborator

aweary commented Apr 29, 2016

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

@nvdbleek
Copy link

nvdbleek commented Apr 29, 2016

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

@aweary
Copy link
Collaborator

aweary commented May 18, 2016

We just merged #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

@aweary aweary closed this as completed May 18, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants