TypeError: Cannot read property 'child' of undefined during mounting in enzyme unit tests

3.4k Views Asked by At

I need to mount a class component as I need to test all the components being rendered by it. But I think I am making some mistake in passing the props in it. This is my component:

class Marketing extends PureComponent {

    constructor(props) {
        super(props);

        this.state = this.defaultState(props);
    }

    // Default state of current step
    defaultState = props => {
        const stepData = getStepDataFromPayload("marketing", props.payloadData);
        return {
            displayname: "",
            logourl: "",
            summary: "",
            description: "",
            highlights: [],
            imageurls: [],
            videourls: [],
            redirectUrl: "",
            showCheckBox: false,
            logoCheckbox:false,
            ...stepData
        };
    };
render(){
/*Custom Components*/
}}
export default Marketing;

I tried something like this: I checked the stepData data from the debugger in chrome tools and put it like this:

const stepData={
    description: "summary",
    displayname: "mkpl_plugin_gypirtterqusmsyqycjquskpqetnguflwstkbjtc_537831429771052714050",
    highlights: [
        "Cloud management software",
        "Application management",
        "Storage and availability",
        "Networking and security products"
    ],
    imageurls: [
        "https://dev-cdn.market.csp.vmware.com/691fd5ea-44ff-4086-84dd-2ab199d8df9e/media-files/logo_2.png",
        "https://dev-cdn.market.csp.vmware.com/691fd5ea-44ff-4086-84dd-2ab199d8df9e/media-files/logo_2.png",
        "https://dev-cdn.market.csp.vmware.com/691fd5ea-44ff-4086-84dd-2ab199d8df9e/media-files/logo_2.png"
    ],
    islistingproduct: false,
    logourl: "https://dev-cdn.market.csp.vmware.com/691fd5ea-44ff-4086-84dd-2ab199d8df9e/media-files/logo_1.png",
    redirectUrl: "",
    summary: "VMware, Inc. is an American cloud computing and virtualization technology company with headquarters in California.commercially successful com",
    videourls: [
        "https://www.youtube.com/watch?v=SDobPYHk_sQ",
        "https://www.youtube.com/watch?v=rNG5dIVe8vc"
    ]

};

const defaultProps={
    displayname: "",
    logourl: "",
    summary: "",
    description: "",
    highlights: [],
    imageurls: [],
    videourls: [],
    redirectUrl: "",
    showCheckBox: true,
    logoCheckbox: true,
    isListing: true,
    updateActionButtons: jest.fn(),
    ...stepData
};

describe("should render all the inner components", () => {
   it("checking the conditional rendering calls", ()=>{
   const newWrapper= mount(<Marketing {...defaultProps}/> );
   });
});

Here I get the error: TypeError: Cannot read property 'child' of undefined. I am not able to figure out where I am wrong for the props. I cannot use shallow method because I need to the inner elements of the components being rendered. I am new to class components in react. Can anyone correct my mistake here?

1

There are 1 best solutions below

2
axordahaxor On

I've tried your code and it seems that it could be a compatibility issue. What is your package.json like? If you use for example React 16 you need an enzyme adapter of version 16 as well, otherwise it doesn't work. For react 18 there should be adapter 18 and so on.

This following package json managed to run your test, but it seems that the official enzyme support for React has been discontinued since React 16, meaning that you need to use "unofficial" packages to upgrade the support to react 18 (if you use it). This is why I have one of those in the package.json shown here.

Is it good or not to use "unofficial" packages or change the testing environment completely to react testing library or something similar, it is up to you. I'd still consider a change as discontinued software lacks both features and security.

This should still help you in seeing if the problem is really a compability issue which it seems to be. Then decide, what is best for you to continue in the future.

  "dependencies": {
    "@cfaester/enzyme-adapter-react-18": "0.5.1",
    "enzyme": "3.11.0",
    "jest": "28.1.3",
    "prop-types": "15.8.1",
    "react": "18.0.0",
    "react-dom": "18.0.0",
    "react-scripts": "4.0.0"
  },

for reference the test file itself:

import Marketing from "./src/App";
import Enzyme, { mount } from "enzyme";
import Adapter from "@cfaester/enzyme-adapter-react-18";
Enzyme.configure({ adapter: new Adapter() });

Your stepData here.....

describe("should render all the inner components", () => {
  it("checking the conditional rendering calls", () => {
    const newWrapper = mount(<Marketing {...defaultProps} />);
  });
});