Only class components can utilize ReactWrapper::state() in Unit Testing with Jest and Enzyme

Encountering an error while writing unit tests in React using Jest and Enzyme. The error message states: "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);
        });
});

The code snippet above suggests that the CustomerAdd Component is a class component. I am unsure of what is causing the issue with my code. Any assistance in resolving this problem would be greatly appreciated. Thank you.

Answer №1

When exporting your default:

export default withStyles(styles)(CustomerAdd);

You are actually exporting a functional (HOC) wrapper around your class-based component. It doesn't matter if the class name and import in

import CustomerAdd from '../CustomerAdd'

are the same. Your tests import the wrapped version, so when you call .find(CustomerAdd), it returns the HOC instead of your class, making it difficult to work with the instance.

A quick fix: export the class directly as a named export.

export class CustomerAdd extends React.Component{
  ...
}

export default withStyles(styles)(CustomerAdd);

In your tests, use a named import:

import { CustomerAdd } from '../CusomerAdd';

An alternative solution: utilize .dive to access the underlying class-based component:

expect(wrapper.find(CustomerAdd).dive().state('addNewOnSubmit')).toEqual(true);

This method may not be ideal as adding any additional HOCs in your default export will require adjusting related tests with more .dive() calls.

The best approach: avoid testing state, focus on validating the rendered output.

By concentrating on what is being displayed, you safeguard your tests against various refactoring techniques, such as switching to functional components, renaming state/instance members, lifting state up, or connecting to Redux.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Encountering CORS issues while trying to deploy a MERN application on DigitalOcean

Currently, I have set up two servers to run simultaneously. The react frontend is running on port 3000 while the express backend is running on port 8000. Despite this setup, when the frontend needs to make a request to the backend server, it encounters a C ...

Unpacking the information in React

My goal is to destructure coinsData so I can access the id globally and iterate through the data elsewhere. However, I am facing an issue with TypeScript on exporting CoinProvider: Type '({ children }: { children?: ReactNode; }) => void' is no ...

Button to expand or collapse all sections in Ant Design Collapse component

Is there a way to create a button that can expand or collapse all tabs in an ant.design Collapse component? I attempted to modify defaultActiveKey but it seems like this can only be done during page rendering. If possible, could someone share a code snip ...

Can you explain how the functionality of setState operates within React in this specific situation?

I've been working on updating the state of an object in my array. I managed to get it done, but I'm a bit confused about how it works. toggleVisited = countryCode => { var countries = [ ...this.state.countries ]; var countryToChange = c ...

Is there a way to locate a specific word within a sentence using JavaScript

I have these lists of answers: For example: const answerList = [{index: 2, answer: nice}, {index: 5, answer: sunday} ...] similar to that Also, I have a sentence: For instance: "hi i'm theo nice to meet you. how are you" My goal is to identify ...

Tips for reducing button spacing and editing pages without using an ID in the URL in Admin-on-rest

Recently, I delved into the world of admin-on-rest and I'm really impressed with its capabilities. However, I've hit a roadblock with two specific issues and would greatly appreciate some guidance: Issue 1 After creating a custom theme complete ...

React Router malfunctioning on production environment when integrated with an Express backend

My Single Page application is built using React for the frontend and Express for the backend. Within the application, there are two main components: and . The goal is to display the component when the "/"" URL is requested, and show the component for an ...

Disabling select based on conditions in Material UI

I have a component that utilizes the Select component from Material-UI. import Select from "@material-ui/core/Select"; export class RowSelectComponent extends React.Component { render() { const {details, classes, name, displayName, v ...

Is it possible to customize the border-radius for a Raised Button?

After attempting to apply the border-radius in this manner: const styles = { btn:{ height: 30, fontSize: 11, borderRadius: 50 } } I encountered an issue as the desired effect was not achieved. I have reviewed the document ...

What is the best way to determine when a React AG-Grid component has finished rendering its data?

I have developed a function called autoSizeAll to automatically resize my columns based on their contents. My goal is for this resizing to occur every time the grid finishes rendering its data. This is important because a user can click a 'get data&ap ...

Using functions as properties in React.js

I am facing an issue while trying to pass a function as a prop. Although I have done this successfully in the past, now I am getting an error (this.props.functionName is not a function). I have a child component called Navbar and a parent component named ...

Can you provide guidance on implementing StyledComponents within the app folder of Next.js version 13?

Quoting information from the Next.js documentation: Attention: CSS-in-JS libraries that rely on runtime JavaScript are currently not compatible with Server Components. The following libraries are supported in Client Components within the app directory: s ...

What is the solution for resolving the JavaScript error "TypeError: Cannot read property 'map' of undefined"?

I'm encountering an issue while fetching data from the API and trying to map it to display in a table. The problem is that the fetching process doesn't seem to be working properly, resulting in the state remaining undefined when the page loads. I ...

react-router matching search parameters

Visit this link for the example code I attempted to run the example using npm start The query string matching to the route seems to be malfunctioning in the example. When I click on the second one, it activates the wrong item. Click here and notice that ...

React fails to display the content

Starting my React journey with Webpack configuration. Followed all steps meticulously. No error messages in console or browser, but the desired h1 element is not showing up. Aware that React version is 18, yet working with version 17. App.jsx import Reac ...

Manipulating state in React

Currently, I am enrolled in Samer Buna's Lynda course titled "Full-Stack JavaScript Development: MongoDB, Node and React." While working on the "Naming Contests" application, I encountered a piece of code within the App component that has left me puzz ...

Updating a route in Next.js? Make sure to remove the classList as you

Looking to remove a specific class whenever the route changes in Next.js, I've attempted the following approach: React.useEffect(() => { const activatedLink = router.query.tags const classActivated = document.querySelector('.'+activated ...

"Proceeding without waiting for resolution from a Promise's `.then`

I am currently integrating Google Identity Services for login on my website. I am facing an issue where the .then function is being executed before the Promise returned by the async function is resolved. I have temporarily used setTimeout to manage this, b ...

The combination of Object.keys() and the find function

Having trouble figuring out why I'm getting an error when attempting to use ES6 .find on the following data in order to retrieve the record with id number 3. { {id:10,title:'Dairy & Eggs'} {id:7,title:'Laundry & Household'} {id ...

A React component enclosed within a useCallback function

According to the React docs, to prevent a Child component from re-rendering in certain cases, you need to wrap it in useMemo and pass down functions in useCallback within the Parent component. However, I'm confused about the purpose of this implementa ...