enzyme: hasClass returns false unexpectedly in v3

Hi! I have the following piece of code (simplified), in my Jest/Enzyme based test suite:

    it('toggles calendar visibility on label click', () => {
        const component = (
            <DatePicker />
        );

        const datePicker = mount(component).find('.DatePicker');

        // Opening
        datePicker.find('.DatePicker__button').simulate('click');

        console.log(datePicker.getDOMNode().className);
        console.log(datePicker.hasClass('open'));

        expect(datePicker.hasClass('open')).toBe(true);

        // Closing
        datePicker.find('.DatePicker__button').simulate('click');

        expect(datePicker.hasClass('open')).toBe(false);
    });

I’m getting false on hasClass unexpectedly. The two console.logs I have in the code return as follows:

image

I’ve tried multiple combinations, like datePicker.getDOMNode().hasClass but these are not working either.

Thanks in advance for help!

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 6
  • Comments: 23 (4 by maintainers)

Commits related to this issue

Most upvoted comments

@antonyoneill’s https://github.com/airbnb/enzyme/issues/1177#issuecomment-332658634 was correct for me; .hasClass failed, but dumping .html() shows that the expected class does actually show up. Tweaking things to instead do .render().hasClass() instead of just .hasClass() then has the tests passing (using the cheerio wrapper to do the test instead).

Hi All, any update on this?

Also, the v15 adapter and v16 give different results as well. I upgrade to enzyme 3 with v15, then I’m trying to switch to v16, and some of my tests are failing again. All are using mount, and it seems it’s always that the component should be updated but it’s not the case. Calling .update() doesn’t solve anything.

@ljharb got it, thanks. And I’m sorry, I didn’t mean to be disrespectful.

Sorry, I don’t check my notifications on here enough. Ended up here again while searching around for another issue and saw that you responded to me. I ended up solving that issue, and I don’t think it was a bug in Enzyme, just a flawed test in my code. That one might have required a .forceUpdate() followed by an .update() to get to the state I needed. Latest issue has something to do with hasClass not responding the way I expect, but I’m 99.99% sure that my expectation is off. Nothing for you to worry about. Thanks for keeping an eye on the issues though! 😃

Could this be related to #1163? I’m seeing some interesting failures along these lines. If you were to console.log(getDatePicker().html() I think you’ll find that the element does have the ‘open’ class.

Hi All, Getting the same error for finding the classname and it returns false even though the class exists. Any update on this?

I hope I’m on the same page here, but it seems like this isn’t even related to dynamic updating of the component. mount and shallow show different behaviours.

With this test case I get one pass and one fail.

repro.test.jsx

import {mount, shallow} from 'enzyme'
import React from 'react'

const Comp = () => {
    return (
        <div className="test">
            <p>Hello world</p>
        </div>
    )
}

test('It finds the className on the mount()\'d wrapper', () => {
    const mountWrapper = mount(<Comp />)
    expect(mountWrapper.hasClass('test')).toBe(true)
})

test('It finds the className on the shallow()\'d wrapper', () => {
    const shallowWrapper = shallow(<Comp />)
    expect(shallowWrapper.hasClass('test')).toBe(true)
})
npm test -- repro

 FAIL  ./repro_test.js
  ● It finds the className on the mount()'d wrapper

    expect(received).toBe(expected)

    Expected value to be (using ===):
      true
    Received:
      false

      at Object.<anonymous> (repro_test.js:14:43)
          at Promise (<anonymous>)
      at Promise.resolve.then.el (node_modules/p-map/index.js:42:16)
          at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:188:7)

  ✕ It finds the className on the mount()'d wrapper (21ms)
  ✓ It finds the className on the shallow()'d wrapper (4ms)

you’ll actually need to not call datePicker.update() but instead do:

const wrapper = mount(component);
const getDatePicker = () => wrapper.find('.DatePicker');

and do wrapper.update() and getDatePicker() afterwards or something like that. .update() should be called on the root.