I am having an error with rendering a component in the react unit test. I have tried the same with enzyme gives the same error only for mount method.
The error message is:
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
The above error occurred in the component: in div (created by Header) in li (created by ForwardRef(ButtonBase)) in ForwardRef(ButtonBase) (created by WithStyles(ForwardRef(ButtonBase))) in WithStyles(ForwardRef(ButtonBase)) (created by ForwardRef(ListItem)) in ForwardRef(ListItem) (created by WithStyles(ForwardRef(ListItem))) in WithStyles(ForwardRef(ListItem)) (created by ForwardRef(MenuItem)) in ForwardRef(MenuItem) (created by WithStyles(ForwardRef(MenuItem))) in WithStyles(ForwardRef(MenuItem)) (created by Header) in ul (created by ForwardRef(List)) in ForwardRef(List) (created by WithStyles(ForwardRef(List))) in WithStyles(ForwardRef(List)) (created by ForwardRef(MenuList)) in ForwardRef(MenuList) (created by ForwardRef(Menu)) in div (created by ForwardRef(Paper)) in ForwardRef(Paper) (created by WithStyles(ForwardRef(Paper))) in WithStyles(ForwardRef(Paper)) (created by Transition) in Transition (created by ForwardRef(Grow)) in ForwardRef(Grow) (created by Unstable_TrapFocus) in Unstable_TrapFocus (created by ForwardRef(Modal)) in div (created by ForwardRef(Modal)) in ForwardRef(Portal) (created by ForwardRef(Modal)) in ForwardRef(Modal) (created by ForwardRef(Popover)) in ForwardRef(Popover) (created by WithStyles(ForwardRef(Popover))) in WithStyles(ForwardRef(Popover)) (created by ForwardRef(Menu)) in ForwardRef(Menu) (created by WithStyles(ForwardRef(Menu))) in WithStyles(ForwardRef(Menu)) (created by Header) in div (created by Header) in div (created by Header) in Header (created by Login) in div (created by Login) in div (created by Login) in Login in Router in GlobalProvider (created by WrapperComponent) in WrapperComponent
Heres the code
1. login.js
path: src/components/login/index.js
// Login component
import React, { useState, useEffect } from 'react';
import CustomButton from '../basic-components/button';
import Textfield from '../basic-components/textfield';
import Cross from '../../images/cross-icon.svg';
import { useHistory } from 'react-router-dom';
import ErrorAlert from '../basic-components/snackbar';
import Header from '../basic-components/header';
import Cookies from 'js-cookie';
import { useGlobalState, useGlobalDispatch } from '../context/globalContext';
import './style.scss';
const Login = (props) => {
// const [email,setEmail] = useState('');
const [isCookieOn,setCookieOn] = useState(false);
const [errors,setErrors] = useState({errorSeverity:'',openSnackbar:false,msg:'',isError:false});
const history = useHistory();
const { email } = useGlobalState();
const globalDispatch = useGlobalDispatch();
const getVerificationCode = () => {
if(errors.isError || !email){
setErrors(errors=>({...errors,openSnackbar:true,errorSeverity:'error',msg:"Please enter valid email"}));
return
}
history.push('/emailverification');
}
const setSnackbar = (value) => {
setErrors(errors=>({...errors,openSnackbar:value}));
}
const onEmailChange = debounce((evt) => {
globalDispatch({type:'setEmail',payload:evt});
validateEmail(evt);
},500);
const validateEmail = (value) => {
const expression = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
if(value && !expression.test(value))
setErrors(errors=>({...errors,isError:true,msg:"Please enter valid email"}));
else
setErrors(errors=>({...errors,isError:false}));
}
const setCookie = () => {
if(!isCookieOn){
Cookies.set("CookieConsent",true);
setCookieOn(true);
}
}
useEffect(()=>{
let cookie = Cookies.get("CookieConsent");
if(cookie){
setCookieOn(cookie);
}
props.setPage(true);
return () => {
props.setPage(false);
}
},[])
return (
<div className="login">
<div className="wrapper">
<Header/>
<div className="container">
<div className='images'>
</div>
<p className='subtitle'>Welcome!</p>
<h1 className='head-text'>Please Sign In</h1>
<div className="inputs">
<Textfield
id="email"
error={errors.isError}
onChange={(e)=>onEmailChange(e.target.value)}
label="Enter your email"
errorMsg={errors.msg}
/>
<CustomButton classes="code-btn" onClick={getVerificationCode} text="Get Code"/>
</div>
</div>
</div>
{!isCookieOn && <div className='cookies'>
<div className='header'>
<span className='text'>Cookie Talk</span><img src={Cross} className='cross' onClick={setCookie} alt="cancle cookies"/>
</div>
<p className='content'>We use cookies to enhance your browsing exeprience. By continuing to browse or closing this banner, you consent to our use of cookies.</p>
</div>}
<ErrorAlert
openSnackbar={errors.openSnackbar}
msg={errors.msg}
errorSeverity={errors.errorSeverity}
setSnackbar={setSnackbar}
value={email}
/>
</div>
);
};
function debounce (fn, wait) {
let t
return function () {
clearTimeout(t)
t = setTimeout(() => fn.apply(this, arguments), wait)
}
}
export default Login;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.5.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.5.1/umd/react-dom.production.min.js"></script>
1. login.spec.js
path: src/components/login/login.spec.js.
//login.spec.js
import React from 'react';
import Login from './index';
import {renderHook} from '@testing-library/react-hooks';
import { render, fireEvent } from '@testing-library/react';
describe("Login",()=>{
it("should render properly",()=>{
const wrapper = render(<GlobalProvider><Login setPage={jest.fn()}/></GlobalProvider>);
})
})
1. header.js
path: src/components/basic-components/header/index.js
//Header component
import React, { useState, useEffect } from 'react';
import { useGlobalState,useGlobalDispatch } from '../../context/globalContext';
// import { useProfileState } from '../../context/profileContext';
import {ReactComponent as SearchIcon} from '../../../images/search-icon.svg';
import './header.scss';
import NavDrawer from '../drawer/drawer';
import {DashboardIcon} from '../../SvgComponents/dashboard';
import {SupportIcon} from '../../SvgComponents/support';
import {ProfileIcon} from '../../SvgComponents/profile';
import {SettingsIcon} from '../../SvgComponents/settings';
import {ContactsIcon} from '../../SvgComponents/mycontacts';
import {ReactComponent as SignOut} from '../../../images/signOut.svg';
import {DashboardMenuIcon} from '../../SvgComponents/dashboardmenu';
import {Link,useHistory} from 'react-router-dom';
import Menu from '@material-ui/core/Menu';
import MenuItem from '@material-ui/core/MenuItem';
const Header = () => {
const { currentProfileImg,activePage,activeRoute } = useGlobalState();
const [open,setDrawer] = useState(false);
const [anchorEl, setAnchorEl] = React.useState(null);
const globalDispatch = useGlobalDispatch();
const history = useHistory();
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
const updateNavigation = (route) => {
globalDispatch({type:'setActiveRoute',payload:route});
history.push(`/${route}`);
}
const toggleDrawer = () => {
setDrawer(state=>!state);
}
return (
<div className='header'>
<div className="header-container" style={activePage==='dashboard'?{borderBottom:'1px solid #E0E0E0'}:{}}>
{/* clickable navigation on arrow */}
//removed some unnecessary code
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
className='nav-desktop-menu'
>
<MenuItem onClick={handleClose}>
<div className={`menu ${activeRoute==='fellowprofile' ? 'active' :''}`} onClick={()=>updateNavigation('fellowprofile')}>
<ProfileIcon className='nav-icon' isActive={activeRoute==='fellowprofile' ? true :false}/>
<div className='nav-title'>Profile</div>
</div>
</MenuItem>
<MenuItem onClick={handleClose}>
<div className={`menu ${activeRoute==='settings' ? 'active' :''}`} onClick={()=>updateNavigation('settings')}>
<SettingsIcon className='nav-icon' isActive={activeRoute==='settings' ? true :false}/>
<div className='nav-title'>Settings</div>
</div>
</MenuItem>
<MenuItem onClick={handleClose}>
<div className='menu'>
<SignOut className='nav-icon'/>
<div className='nav-title'>Sign Out</div>
</div>
</MenuItem>
</Menu>
</div>
<NavDrawer openDrawer={open} toggleDrawer={toggleDrawer} userProfile={currentProfileImg }/>
</div>
);
};
export default Header;
./indexfile? - Chris./src/components/index.js)? It looks like a wrong import statement or something similar. - Chris