How do I test child component renders in Parent test

Viewed 858

Getting this error, but component is exported I believe correctly:

Property declarations[0] of VariableDeclaration expected node to be of a type ["VariableDeclarator"] but instead got undefined

Parent Component:

import React from 'react';
import Link from '../link/Link';

import * as Styled from './Header.style';

class Header extends React.Component {
    render() {
        return (
            <Styled.Header>
                <Link href={'/'} passHref>Home</Link>
                <Link href={'/about'} passHref>About</Link>
            </Styled.Header>
        );
    }
}

export default Header;

Child Component:

import React from 'react';
import Link from 'next/link';
import { useRouter } from 'next/router';

import * as Styled from './Link.style';

const NavLink = ({ href, children }) => {
    const router = useRouter();
    const toggleActive = router.pathname === href ? 'active' : null;

    return (
        <Link href={href} passHref>
            <Styled.Link className={toggleActive}>{children}</Styled.Link>
        </Link>
    );
};

export default NavLink;

Parent Test:

jest.mock('./Header.style');
jest.mock('../link/Link', () => {
     const Link = () => <div>Mocked component</div>;
     return Link;
});

import * as React from 'react';
import { mount } from 'enzyme';
import Link from '../link/Link';
import * as Styled from './Header.style';
import Header from './Header';

describe('Header', () => {
    describe('When mounted', () => {
        let wrapper;

        beforeAll(() => {
            wrapper = mount(<Header />);
        });

        it('Should render <Link /> components', () => {
            expect(wrapper.find(Link).length).toBe(2);
        });

        afterAll(() => {
            jest.resetAllMocks();
        });
    });
});

package.json

"dependencies": {
  "next": "^11.1.2",
  "react": "^16.14.0",
  "react-dom": "^16.14.0"
},
"devDependencies": {
  "@babel/plugin-transform-runtime": "^7.15.0",
  "@babel/preset-env": "^7.15.0",
  "@babel/preset-react": "^7.14.5",
  "babel-core": "^6.26.3",
  "babel-eslint": "^10.1.0",
  "babel-jest": "^27.1.0",
  "babel-plugin-styled-components": "^1.13.2",
  "enzyme": "^3.11.0",
  "enzyme-adapter-react-16": "^1.15.6",
  "eslint": "7.32.0",
  "eslint-config-next": "11.1.2",
  "eslint-plugin-react": "^7.25.1",
  "jest-cli": "^27.1.0",
  "jest-styled-components": "^6.3.4",
  "styled-components": "^4.4.1"
}

Is it possible that react hook component (child component) has an issue being mocked for whatever reason. Even if I bring in actual component without mocking wrapper.debug() does not console log it.

2 Answers

Have the same issue after upgrading babel. Haven't found a solution yet but a workaround by extracting the mocks out of the test file into a __mocks__ folder next to the implementation: https://jestjs.io/docs/manual-mocks#mocking-user-modules

Then only the mock line would change, but your test stays as it is:

jest.mock('./Header.style');
jest.mock('../link/Link');

import * as React from 'react';
import { mount } from 'enzyme';
import Link from '../link/Link';
...

Maybe you can try to solve it with jest.spyOn instead. I had a similar problem and could solve it that way

Quick draft (not tested):

import * as React from 'react';
import { mount } from 'enzyme';
import * as Link from '../link/Link'
import * as Styled from './Header.style';
import Header from './Header';

describe('Header', () => {
    describe('When mounted', () => {
        let wrapper;
        let linkSpy;

        beforeAll(() => {
            linkSpy = jest.spyOn(Link, 'Link')
            linkSpy.mockImplementation(() => <div>Link</div>)
            wrapper = mount(<Header />);
        });

        it('Should render <Link /> components', () => {
            // I do not know if this will work anymore, I'm not familiar with enzyme that much
            expect(wrapper.find(Link).length).toBe(2);
        });

        afterAll(() => {
            linkSpy.mockRestore();
            jest.resetAllMocks();
        });
    });
});

Related