enzyme
enzyme copied to clipboard
React.Fragment throws an error on shallow render
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"
}
}
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?
Thanks for the reply.... I simply want to get the text content of the fragment using shallow(fragment).text()
const Component = () => fragment;
const wrapper = shallow(<Component />);
wrapper.text();
Oh I see... that's rather obtuse though, don't you think?
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?
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?
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 />);
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 what is the workaround you used?
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;
}, '');
}
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 some markup </>,
},
};
And then seems legit: shallow(modalState.done.description).text()
@akashuba your workaround could be shallow(<div>{modalState.done.description}</div>).text()
, i suspect