enzyme icon indicating copy to clipboard operation
enzyme copied to clipboard

React.Fragment throws an error on shallow render

Open andrewplummer opened this issue 4 years ago • 12 comments

Hi, this seems like a potentially common issue but I haven't found anything directly addressing it. Enzyme seems to throw the error: ReactShallowRenderer render(): Shallow rendering works only with custom components, but the provided element type was symbol.

when trying to wrap React.Fragment with shallow.

Test code:

import React from 'react';

import Adapter from 'enzyme-adapter-react-16';
import { configure, shallow } from 'enzyme';
configure({ adapter: new Adapter() });

describe('test', () => {

  it('case', () => {
    shallow(<React.Fragment>test</React.Fragment>);
  });

});

My package.json is:

{
  "name": "enzyme",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "devDependencies": {
    "@babel/preset-env": "^7.8.4",
    "@babel/preset-react": "^7.8.3",
    "babel-jest": "^25.1.0",
    "enzyme": "^3.11.0",
    "enzyme-adapter-react-16": "^1.15.2",
    "jest": "^25.1.0",
    "react": "^16.12.0",
    "react-test-renderer": "^16.12.0"
  },
  "scripts": {
    "test": "jest"
  },
  "dependencies": {
    "react-dom": "^16.12.0"
  }
}

andrewplummer avatar Feb 06 '20 10:02 andrewplummer

shallow is meant to take an element, and then wrap what that element renders. What are you testing by passing it a fragment as the top level?

ljharb avatar Feb 06 '20 19:02 ljharb

Thanks for the reply.... I simply want to get the text content of the fragment using shallow(fragment).text()

andrewplummer avatar Feb 07 '20 01:02 andrewplummer

const Component = () => fragment;
const wrapper = shallow(<Component />);
wrapper.text();

ljharb avatar Feb 07 '20 01:02 ljharb

Oh I see... that's rather obtuse though, don't you think?

andrewplummer avatar Feb 07 '20 01:02 andrewplummer

It is, that's true. This seems like a rare use case though - enzyme is designed for testing components (and HTML elements); can you help me understand what your overarching goal is, so that I can understand how enzyme can best meet your use case?

ljharb avatar Feb 07 '20 01:02 ljharb

I mean it's fairly simple... let's say I'm testing that a component/module/what have you is returning the proper error message, such as Please contact [email protected], however that email address has to be a link so it can no longer return a string. Instead it wraps it in a fragment to have an <a> tag inside, however I want to test that the message is correct.

This seems like a fairly common use case, don't you think?

andrewplummer avatar Feb 07 '20 01:02 andrewplummer

Hmm, I think it's common to have a component that renders this, but not to have an exposed function that returns it and thus needs to be unit-tested.

I'll think about if there's a way to make shallow(<>{children}</>) be the same as:

const C = () => <>{children}</>;
shallow(<C />);

ljharb avatar Feb 07 '20 01:02 ljharb

Thanks! I think it might be quite useful... In the meantime I have a workaround, though so it's not a pressing issue for me.

andrewplummer avatar Feb 07 '20 05:02 andrewplummer

@andrewplummer what is the workaround you used?

andreieftimie avatar Jan 13 '21 07:01 andreieftimie

It's been a while now... seems like I just hacked in a generic function to recursively get an element's text along the lines of:

function getText(props) {
  return props.children.reduce((str, el) => {
    if (typeof el === 'string') {
      str += el;
    } else {
      str += getText(el);
    }
    return str;
  }, '');
}

andrewplummer avatar Jan 13 '21 14:01 andrewplummer

Same issue, in my case I'm keeping state of modal window in structure like this:

const modalState = {
  done: {
    title: "Congrats",
    description: <>And here we have&nbsp;some markup </>,
  },
};

And then seems legit: shallow(modalState.done.description).text()

akashuba avatar Aug 27 '21 12:08 akashuba

@akashuba your workaround could be shallow(<div>{modalState.done.description}</div>).text(), i suspect

ljharb avatar Aug 27 '21 16:08 ljharb