So very new to the community, because I usually find the answer to my questions just by searching the community. But this one I can’t figure out.
My Setup
I am using NextJS just as a framework application, so I don’t use any of its API abilities. So far no tests implemented, but now I got more time on my hands. I want to implement tests using Jest and later on implementing some e2e such as playwright. But for now Jest.
The Problem
So I am implementing Jest in my application, but somehow cannot run the test because I am using a Dynamic Icon Component within my application.
So what is this icon component I am talking about. I got tired of importing icons one by one in each page. So decided to create one component that has the name attribute, so I can pass it any SVG name and it would just render it on my screen.
// Icon.jsx
import Company from './icons/company.svg';
const iconTypes = {
'company': Company,
}
const Icon = ({ name, ...props }) => {
let Icon = iconTypes[name];
return <Icon {...props} />;
};
export default Icon;
// next.config.json
module.exports = {
webpack(config) {
config.resolve.fallback = { fs: false };
config.module.rules.push({
test: /.svg$/,
use: ["@svgr/webpack"]
});
return config;
},
eslint: {
// Warning: This allows production builds to successfully complete even if
// your project has ESLint errors.
ignoreDuringBuilds: true,
},
reactStrictMode: true,
}
So this pretty much allows me to import an Icon by simply saying on anypage:
<Icon name="company" />
Now when implementing Jest, this component causes a lot of troubles with running my tests. I get the following error, when running my test:
Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check your code at Icon.jsx:119.
...
117 | console.log(1111111, name)
118 | let Icon = iconTypes[name];
> 119 | return <Icon {...props} />;
| ^
120 | };
121 |
122 | export default Icon;
at printWarning (node_modules/react/cjs/react.development.js:220:30)
at error (node_modules/react/cjs/react.development.js:196:5)
at createElementWithValidation (node_modules/react/cjs/react.development.js:2215:7)
at Icon (res/images/Icon.jsx:119:10)
at renderWithHooks (node_modules/react-dom/cjs/react-dom.development.js:14985:18)
at mountIndeterminateComponent (node_modules/react-dom/cjs/react-dom.development.js:17811:13)
at beginWork (node_modules/react-dom/cjs/react-dom.development.js:19049:16)
So this error message I usually get when I pass in a name of an icon that does not exist.
So at this point I’m a bit confused on how to handle this? Is there a way to ignore this component when running the test? Or run it somehow.
Some things I already tried
//jest.config.js
module.exports = {
"transform": {
"^.+\.jsx?$": "babel-jest",
"^.+\.svg$": "<rootDir>/svgTransform.js"
},
setupFilesAfterEnv: ["./jest.setup.js"],
moduleNameMapper: {
"^@/libs(.*)$": "<rootDir>/libs$1",
"^@/res(.*)$": "<rootDir>/res$1",
"^@/store(.*)$": "<rootDir>/store$1",
"^@/pages(.*)$": "<rootDir>/pages$1",
'^.+\.(css|less|scss)$': '<rootDir>/styleMock.js'
},
};
// svgTransform.js
module.exports = {
process() {
return 'module.exports = {};';
},
getCacheKey() {
// The output is always the same.
return 'svgTransform';
},
};