enzyme icon indicating copy to clipboard operation
enzyme copied to clipboard

ReactWrapper::state() can only be called on class components

Open ajeesh-s opened this issue 6 years ago • 9 comments

Writing unit testing in react using jest and enzyme. While checking with a component state , it throws an error "ReactWrapper::state() can only be called on class components ".

import React from 'react';
import { mount } from 'enzyme';
import expect from 'expect';
import CustomerAdd from '../CustomerAdd'
import MUITheme from '../../../../Utilities/MUITheme';
import { ThemeProvider } from '@material-ui/styles';

describe('<CustomerAdd />', () => {
    const wrapper = mount(
        <ThemeProvider theme={MUITheme}>
          <CustomerAdd {...mockProps}></CustomerAdd>
        </ThemeProvider>
        );
        test('something', () => {
            expect(wrapper.find(CustomerAdd).state('addNewOnSubmit')).toEqual(true);
        });
});

In the above code CustomerAdd Component is class component.I don't what wrong with my code. Can any one help me out of this problem. Thanks in advance.

ajeesh-s avatar Oct 17 '19 11:10 ajeesh-s

Are you sure CustomerAdd is a class component, and not an SFC, or wrapped in an HOC that's one? What's the source of CustomerAdd?

ljharb avatar Oct 19 '19 05:10 ljharb

@ajeesh-s I have the problem same you. You can check where it is used and expect to it ex:

<Foo>
  <Bar open={isOpen}/>
</Foo>

instead of check state isOpen of Foo component, i check wrap.find(Bar).prop('open')

tuvudu avatar Oct 24 '19 01:10 tuvudu

Same issue, to be more specific though: My component uses React hooks. Which might be the case after all. If that's the case, is there any other counter solution to this issue?

exapsy avatar Dec 23 '19 13:12 exapsy

@exapsy function components have no state; the useState hook is a misleading name as it does not, in fact, make the function stateful - all it does is notify React to store information in a side channel, which is state react holds, not your component.

As such, unless React itself provides a way for testing tools to directly interact with hook state, it remains impossible/impractical for testing tools to have any direct interaction with it.

ljharb avatar Dec 23 '19 21:12 ljharb

Are you sure CustomerAdd is a class component, and not an SFC, or wrapped in an HOC that's one? What's the source of CustomerAdd?

@ljharb what is the solution if I want to check the state of my class component which is wrapped in an HOC that is a function component? Ideally I'd like to avoid changing that HOC.

indefinitelee avatar Dec 01 '21 17:12 indefinitelee

@indefinitelee you can .dive().state() (one dive per HOC)

ljharb avatar Dec 01 '21 17:12 ljharb

@ljharb does.dive() work when we use mount(<MyComponent />) ? i thought we had to use .get(int) in that case

indefinitelee avatar Dec 01 '21 18:12 indefinitelee

@indefinitelee no, .dive() is only for shallow. in that case you need to descend down with .find or .childAt().

ljharb avatar Dec 01 '21 18:12 ljharb

many thanks for the responses!

indefinitelee avatar Dec 01 '21 18:12 indefinitelee