Enzyme: `.exists()` doesn't work as expected

Created on 11 Oct 2018  路  6Comments  路  Source: enzymejs/enzyme

Describe the bug
.exists() returns true when you return null on a component

To Reproduce

function Something () {
  return null
}

test('something exists', () => {
  const obj = shallow(<Something />)
  // throws an error because `obj.exists()` returns true
  expect(obj.exists()).toBeFalsy()
})

Expected behavior
.exists() should return false because there's nothing to be rendered

Additional context
The reason it's failing is because it's testing this.length > 0 which returns true because if you log out the private variable of wrapper[NODES] it returns [ null ].

for now I've just overwritten the default .exists() function in my setup until this is resolved

Enzyme.ShallowWrapper.prototype.exists = function exists (selector = null) {
  if (arguments.length > 0 && typeof selector !== 'string') {
    throw new TypeError('`selector` argument must be a string, if present.')
  }
  if (typeof selector === 'string') {
    return this.find(selector).exists()
  }
  return this.getNodesInternal().filter(Boolean).length > 0
}
question

Most helpful comment

Sounds good! IMO, this ticket has been addressed and your recommendation to use isEmptyRender was the right call. Given that, we can update the documentation and add tests like you suggested to avoid confusion.

Via https://airbnb.io/enzyme/docs/api/ReactWrapper/exists.html

Returns whether or not the current node exists.

I could see how you could expect a rendered component that returns null to use .exists() and expect it to return false. Maybe thats one of the aspects we can expand on?

All 6 comments

You want .isEmptyRender() instead; .exists() indeed is doing the correct thing - the wrapper exists, whether it renders null or not.

We can either close this ticket, as "answered" or keep it open to discuss how exists should behave in this circumstance. Or close this issue and create a new issue discussing it.

Notes: As per the documentation and conversation with @ljharb https://airbnb.io/enzyme/docs/api/ShallowWrapper/exists.html, when a selector is not passed in, it should return whether or not the node existsReturns whether or not the current node exists. The discussion should be about the definition of exists and how to proceed with this question/bug.

@ljharb any idea on the direction we should go with this?

Thanks

I think if we can confirm that both exists and isEmptyRender are behaving as expected for both shallow and mount (possibly with added test cases), then we should improve the documentation for both to avoid confusion.

Sounds good! IMO, this ticket has been addressed and your recommendation to use isEmptyRender was the right call. Given that, we can update the documentation and add tests like you suggested to avoid confusion.

Via https://airbnb.io/enzyme/docs/api/ReactWrapper/exists.html

Returns whether or not the current node exists.

I could see how you could expect a rendered component that returns null to use .exists() and expect it to return false. Maybe thats one of the aspects we can expand on?

The docs have been updated.

Was this page helpful?
0 / 5 - 0 ratings