Do you want to request a _feature_ or report a _bug_?
Bug
What is the current behavior?
First, I'm not sure if this is a problem with Jest or with Enzyme, but I first noticed this when migrating another project from Mocha to Jest.
When mounting a stateless function component with Enzyme, the component name is
preserved when running jest, but not when running jest --coverage. This is
causing unit tests to fail when generating coverage that otherwise succeed.
For example, when mounting the component
const Foo = () => <div>Foo</div>
results in
<Foo>
<div>
Foo
</div>
</Foo>
but when generating coverage, it results in
<Component>
<div>
Foo
</div>
</Component>
If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal repository on GitHub that we can npm install and npm test.
git clone https://github.com/esturcke/jest-stateless-coverage-bug
npm install
CI=1 npm test
CI=1 npm test -- --coverage
What is the expected behavior?
Testing with --coverage succeeds.
Run Jest again with --debug and provide the full configuration it prints. Please mention your node and npm version and operating system.
node v6.4.0
npm v3.10.3
OS X 10.11.6
debug output
Can you try updating to Node 6.5 and see if this still happens? It does some things differently in how it infers function names.
Just updated to the latest via Homebrew:
$ node --version
v6.7.0
but I'm getting the same result.
yeah this kind of sucks. Istanbul wraps functions with other anonymous functions and we take the function name that node gives to the rendered component :(
You can also add displayName to the component.
Yup displayName works:
const Foo = () => <div>Foo</div>
Foo.displayName = "Foo"
So is the issue with Istanbul or is there something Jest/React can do? The interesting thing is that the way I had Mocha/Istanbul set up didn't seem to run into this problem. It only happened when I tried to use Jest to run the same tests.
Other than that the migration was very painless and Jest "just worked".
Passing the component to find() rather than a string looks like it might fix the unit tests as well:
describe("<Foo>", () => {
it("renders 'Foo'", () => {
const wrapper = mount(<Foo/>)
console.log(wrapper.debug())
return expect(wrapper.find(Foo).text()).to.be.equal("Foo")
})
})
Maybe this is actually the correct way to use Enzyme and it just happened to usually work with strings.
@cpojer is there a potential solution for this in Instanbul, or is just setting displayName preferred over name anyway?
I don't fully understand why this issue is closed - I am still running into it. The suggestion to pass the component instead of a string to .find() works fine, but this bug becomes problematic when you use expect(wrapper).toMatchSnapshot().
Same here
Try:
const Sfc = (props) => <div>{props.text}</div>;
Sfc.displayName = 'SfcWithAName';
export default Sfc;
See https://github.com/airbnb/enzyme/blob/master/packages/enzyme/src/Debug.js#L11-L15
@stief510 I was able to make it work with a babel plugin: https://www.npmjs.com/package/babel-plugin-transform-react-stateless-component-name
Most helpful comment
Yup
displayNameworks:So is the issue with Istanbul or is there something Jest/React can do? The interesting thing is that the way I had Mocha/Istanbul set up didn't seem to run into this problem. It only happened when I tried to use Jest to run the same tests.
Other than that the migration was very painless and Jest "just worked".