wrapper.state() and wrapper.instance().state() are both null react/jest/enzyme - reactjs

As the subject line says, state is null and I cannot see why.
React 16
Jest
Enzyme
Webpack 4
Babel
(package.json below)
I've hit up pretty much every possible link searchable (although, admittedly I likely just missed 'the one' that tells me what I've done wrong).
If someone responds with a simple 'check here' link and it solves all my problems I'll close this (after I go chew some rocks for a while) and happily move on, but after a few hours of beating myself against the wall I'm close to going back to Jasmine... it at least worked there. :\
Output:
PASS __tests__\Components\ListBox.spec.js
● Console
console.log __tests__\Components\ListBox.spec.js:33
_____ wrapper: null
console.log __tests__\Components\ListBox.spec.js:34
____ instance: null
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 0.985s, estimated 1s
Ran all test suites related to changed files.
Here is my package.json:
{
"name": "module",
"version": "1.0.1",
"author": "thanks all!",
"description": "",
"license": "MIT",
"main": "src/main.jsx",
"jest": {
"automock": true,
"testEnvironment": "jsdom",
"verbose": false,
"setupFiles": [
"raf/polyfill"
],
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
"\\.(css|less)$": "identity-obj-proxy"
},
"moduleFileExtensions": [
"js",
"jsx",
"es6"
],
"unmockedModulePathPatterns": [
"react",
"react-dom",
"react-addons-test-utils",
"enzyme"
],
"modulePaths": [
"<rootDir>/src",
"<rootDir>/src/app",
"<rootDir>/src/app/Components"
],
"transform": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga|js|jsx|es6)$": "./node_modules/babel-jest"
}
},
"jestWebpackResolver": {
"webpackConfig": "./webpack.config.js"
},
"scripts": {
"start": "webpack-dev-server --env=dev --colors --hot --mode development -d",
"build": "webpack --env=dev --progress --profile --colors --mode development",
"release": "webpack --env=prod --progress --profile --colors --mode production",
"watch": "webpack --env=dev --profile --colors --watch --watch-poll --mode development",
"lint": "eslint ./src/**.js",
"coverage": "jest --coverage",
"test": "jest",
"test-watch": "jest --coverage --watch --colors",
"testw": "jest --watch --colors"
},
"devDependencies": {
"babel-core": "^6.26.0",
"babel-eslint": "^8.2.2",
"babel-jest": "^22.4.1",
"babel-loader": "^7.1.4",
"babel-preset-env": "^1.6.1",
"babel-preset-stage-3": "^6.24.1",
"core-js": "^2.5.5",
"css-loader": "^0.28.10",
"enzyme": "^3.3.0",
"eslint": "^4.18.2",
"eslint-config-airbnb": "^16.1.0",
"eslint-import-resolver-webpack": "^0.9.0",
"eslint-loader": "^2.0.0",
"eslint-plugin-import": "^2.9.0",
"eslint-plugin-jsx-a11y": "^6.0.3",
"eslint-plugin-react": "^7.7.0",
"identity-obj-proxy": "^3.0.0",
"jest": "^22.4.2",
"jest-enzyme": "^6.0.0",
"jest-webpack-resolver": "^0.3.0",
"node-sass": "^4.5.3",
"object-assign": "^4.1.1",
"raf": "^3.4.0",
"react-hot-loader": "^4.0.0",
"react-test-renderer": "^16.3.2",
"sass-loader": "^6.0.6",
"style-loader": "^0.20.3",
"webpack-dev-server": "^3.1.1",
"webpack-merge": "^4.1.2"
},
"dependencies": {
"babel-preset-react": "^6.24.1",
"clean-webpack-plugin": "^0.1.19",
"enzyme-adapter-react-16": "^1.1.1",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"flux": "^3.1.3",
"font-awesome": "^4.7.0",
"html-webpack-plugin": "^3.0.6",
"jest-environment-enzyme": "^6.0.0",
"lodash": "^4.17.5",
"moment": "^2.22.0",
"node-rest-client": "^3.1.0",
"npm": "^5.7.1",
"prop-types": "^15.6.1",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-router": "^4.2.0",
"react-router-dom": "^4.2.2",
"webpack": "^4.2.0",
"webpack-bundle-analyzer": "^2.11.1",
"webpack-cli": "^2.0.13",
"webpack-dev-middleware": "^3.0.1"
}
}
Here is my spec file:
/*
eslint-disable
react/jsx-filename-extension,
import/first,
no-console
*/
jest.dontMock('enzyme');
jest.dontMock('react');
jest.dontMock('react-dom');
import React from 'react';
import Adapter from 'enzyme-adapter-react-16';
import { configure, shallow, mount } from 'enzyme';
import { ListBox } from 'app/Components/ListBox/ListBox';
configure({ adapter: new Adapter() });
jest.dontMock('app/Components/ListBox/ListBox');
describe('<ListBox {...props} />', () => {
let wrapper;
let list;
const items = [{ text: 'test', key: 1 }];
describe('<ListBox {...props} />', () => {
beforeEach(() => {
wrapper = mount(<ListBox items={items} />);
list = wrapper.instance();
});
it('Can mount without error', () => {
expect(list).toBeInstanceOf(ListBox);
});
it('accepts an array of items to display and stores them in local state.', () => {
console.log(`_____ wrapper: ${wrapper.state()}`);
console.log(`____ instance: ${wrapper.instance().state}`);
});
});
});
Here is the beginning of the component under test:
import React from 'react';
export default class ListBox extends React.Component {
constructor(props) {
super(props);
this.state = {
items: this.props.items
}
}
render() {
return <div>div</div>;
}
}
export { ListBox };

Solved my own problem. Setting automock to false in the package.json and then explicitly mocking/unmocking as needed resolved the issue for me.
Hopefully this helps others in the future.

Related

svgr/webpack Not Working With Webpack 5 and SingleSpa

I been struggling with this for a week, I been reading another Stackoverflow questions and the SVGR/WEBPACK documentation but I'm unable to solve this.
I wanted to upgrade an old react single-spa application but it had a lot of conflicting dependencies so I simply went and created a new one using the Single Spa Playground web application, everything works great but I can't get my SVG'S as React Components with SVGR/WEBPACK.
The error:
webpack.config.js
const webpackMerge = require("webpack-merge").merge;
const singleSpaDefaults = require("webpack-config-single-spa-react-ts");
module.exports = (webpackConfigEnv, argv) => {
const defaultConfig = singleSpaDefaults({
orgName: "testorg",
projectName: "testproj",
webpackConfigEnv,
argv,
});
return webpackMerge(defaultConfig, {
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: ["style-loader", "css-loader", "sass-loader"],
},
{
test: /\.svg$/,
use: ["#svgr/webpack"],
},
],
},
});
};
How I'm importing the svg
import TestImg from "../../assets/icons/testimage.svg";
How I'm using the SVG
<TestImg />
declarations.d.ts
I'm not entirely sure how does this works but I also removed this and it's the same.
declare module "*.svg" {
const content: React.FC<React.SVGAttributes<SVGElement>>;
export default content;
}
package.json
{
"name": "#testorg/testproj",
"scripts": {
"start": "webpack serve",
"start:standalone": "webpack serve --env standalone",
"build": "concurrently npm:build:*",
"build:webpack": "webpack --mode=production",
"analyze": "webpack --mode=production --env analyze",
"lint": "eslint src --ext js,ts,tsx",
"format": "prettier --write .",
"check-format": "prettier --check .",
"test": "cross-env BABEL_ENV=test jest",
"watch-tests": "cross-env BABEL_ENV=test jest --watch",
"prepare": "husky install",
"coverage": "cross-env BABEL_ENV=test jest --coverage",
"build:types": "tsc"
},
"devDependencies": {
"#babel/core": "^7.15.0",
"#babel/eslint-parser": "^7.15.0",
"#babel/plugin-transform-runtime": "^7.15.0",
"#babel/preset-env": "^7.15.0",
"#babel/preset-react": "^7.14.5",
"#babel/preset-typescript": "^7.15.0",
"#babel/runtime": "^7.15.3",
"#testing-library/jest-dom": "^5.14.1",
"#testing-library/react": "^12.0.0",
"#types/testing-library__jest-dom": "^5.14.1",
"babel-jest": "^27.0.6",
"concurrently": "^6.2.1",
"cross-env": "^7.0.3",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.3.0",
"eslint-config-ts-react-important-stuff": "^3.0.0",
"eslint-plugin-prettier": "^3.4.1",
"husky": "^7.0.2",
"identity-obj-proxy": "^3.0.0",
"jest": "^27.0.6",
"jest-cli": "^27.0.6",
"prettier": "^2.3.2",
"pretty-quick": "^3.1.1",
"sass": "^1.56.2",
"sass-loader": "^13.2.0",
"ts-config-single-spa": "^3.0.0",
"typescript": "^4.3.5",
"webpack": "^5.75.0",
"webpack-cli": "^4.8.0",
"webpack-config-single-spa-react": "^4.0.0",
"webpack-config-single-spa-react-ts": "^4.0.0",
"webpack-config-single-spa-ts": "^4.0.0",
"webpack-dev-server": "^4.0.0",
"webpack-merge": "^5.8.0"
},
"dependencies": {
"#datepicker-react/hooks": "^2.8.4",
"#svgr/webpack": "^6.5.1",
"#types/jest": "^27.0.1",
"#types/react": "^17.0.19",
"#types/react-dom": "^17.0.9",
"#types/systemjs": "^6.1.1",
"#types/webpack-env": "^1.16.2",
"date-fns": "^2.29.3",
"prop-types": "^15.8.1",
"react": "^17.0.2",
"react-datepicker": "^4.8.0",
"react-dom": "^17.0.2",
"react-modal": "^3.16.1",
"react-number-format": "^5.1.2",
"react-toastify": "^6.2.0",
"single-spa": "^5.9.3",
"single-spa-react": "^4.3.1",
"styled-components": "^5.3.6"
},
"types": "dist/testorg-testproj.d.ts"
}
The only way it works
The only way I got it working is uninstalling #svgr/webpack and using my imported svg inside of an img tag, as a source.
<img src={TestImg} alt='' width='200' height='200' />
But is not what I want, I need to be able modify the svg fill by props and that's why I need it as a React Component.
Also, I have a LOT of icons and logos in this project, so manually creating a React Component in my project for each image/icon it's not the solution I'm looking for.
Additional information 1
I put a console log for the TestImg and it shows an url, clearly it's not importing it as a component
If I go to the url this is what it shows:
Additional information 2
import { ReactComponent as TestImg } from "../../assets/icons/testimage.svg"
Doesn't work either, it says:
Can't import the named export 'ReactComponent' (imported as 'TestImg') from default-exporting module (only default export is available)

React: Typescript or Babel error - You may need an appropriate loader to handle this file type

I have a custom hook and it works great! However, I'm getting Typescript errors if I simply use React.useState and React.useEffect. To fix this, I import in React and use (React as any).useState and (React as any).useEffect and then I get the following error that doesn't let me compile.
Hook:
import * as React from 'react';
import imageApi from 'xcel-api-generator/dist/image';
export const useUserProfileImage = (size, userProfileImage) => {
const [userImage, setUserImage] = (React as any).useState(null);
(React as any).useEffect(() => {
const runEffect = async () => {
const userImageCall = await imageApi.getTypeByImageType( {"imageType": size} )
setUserImage(userImageCall.url);
};
runEffect();
}, [userProfileImage])
return [userImage]
}
Error:
../rsv8-components/src/hooks/userProfileImage.ts 5:43
Module parse failed: Unexpected token (5:43)
You may need an appropriate loader to handle this file type.
|
| export const useUserProfileImage = (size, userProfileImage) => {
> const [userImage, setUserImage] = (React as any).useState(null);
| (React as any).useEffect(() => {
| const runEffect = async () => {
I'm totally clueless when it comes to webpack/babel etc... Could someone help guide me through this! Thanks!
Here is my local package.json file:
{
"name": "rsv8-components",
"version": "0.3.11",
"main": "./dist/module.js",
"types": "./dist/module.d.ts",
"dependencies": {
"#types/react-avatar-editor": "^10.3.5",
"react-avatar-editor": "^12.0.0-beta.0",
"react-scroll-to": "^1.2.2",
"react-slick": "^0.23.1",
"react-slick-deux": "https://github.com/aboorde/react-slick-deux#master",
"slick-carousel": "^1.8.1",
"tslib": "^1.9.3",
"xcel-observer": "*"
},
"peerDependencies": {
"react": "^16.8.0",
"react-bootstrap": "0.32.1",
"react-dom": "^16.8.0",
"react-fontawesome": "^1.6.1",
"react-router-dom": "^4.2.2",
"react-toastify": "^4.1.0",
"recompose": "^0.28.1",
"styled-components": "^2.4.0",
"xcel-asset-service": "*",
"xcel-react-animations": "*",
"xcel-react-core": "*",
"xcel-redux-orm": "*",
"xcel-util": "*"
},
"scripts": {
"start": "react-scripts-ts start",
"build": "react-scripts-ts build",
"fix-me-test": "react-scripts-ts test --env=jsdom",
"eject": "react-scripts-ts eject",
"dist": "tsc --declaration",
"dist:watch": "tsc --declaration --watch",
"storybook": "start-storybook -p 6006 -c .storybook"
},
"devDependencies": {
"//": "peerDependencies",
"#storybook/addon-actions": "^4.0.0",
"#storybook/addon-knobs": "^4.0.0",
"#storybook/react": "^4.0.0",
"#types/jest": "^22.2.3",
"#types/node": "^8.9.1",
"#types/react": "^16.3.16",
"#types/react-dom": "^16.0.4",
"#types/react-router-dom": "^4.2.3",
"awesome-typescript-loader": "^3.4.1",
"enzyme-adapter-react-16": "^1.1.0",
"jest": "^23.6.0",
"jest-cli": "^23.4.1",
"jest-styled-components": "4.9.0",
"react": "^16.8.0",
"react-bootstrap": "0.32.1",
"react-dom": "^16.8.0",
"react-fontawesome": "^1.6.1",
"react-router-dom": "^4.2.2",
"react-scripts-ts": "^3.1.0",
"react-toastify": "^4.1.0",
"recompose": "^0.28.1",
"styled-components": "^2.4.0",
"ts-jest": "^22.4.2",
"ts-node": "^5.0.1",
"typescript": "^2.9.0",
"xcel-asset-service": "*",
"xcel-react-animations": "*",
"xcel-react-core": "*",
"xcel-redux-orm": "*",
"xcel-util": "*"
},
"jest": {
"coverageReporters": [
"lcov",
"cobertura",
"text-summary"
],
"testEnvironment": "jsdom",
"moduleFileExtensions": [
"ts",
"tsx",
"js"
],
"testMatch": [
"<rootDir>/src/**/*.test.(ts|tsx)"
],
"collectCoverageFrom": [
"<rootDir>/src/**/*.(ts|tsx)",
"!<rootDir>/src/**/*.test.(ts|tsx)"
],
"transform": {
"\\.(ts|tsx)$": "ts-jest"
}
},
"publishConfig": {
"registry": "Blah blah removed"
}
}

SyntaxError: Unexpected token import at ScriptTransformer._transformAndBuildScript [duplicate]

I'm trying to learn how to do unit testing with React and jest. I've run into the following error:
Unexpected token import
Here are my babel presets:
{
"presets": ["es2015", "stage-0", "react"],
"env": {
"test": {
"plugins": ["transform-es2015-modules-commonjs"]
}
}
}
Here is the file i'm trying to test:
import jest from 'jest';
import React from 'react';
import { shallow } from 'enzyme';
import Step from '../src/components/step.js';
const wrapper = shallow(<Step />);
wrapper.find('a').simulate('click', { preventDefault() {} });
and here is my package.json:
{
"name": "react-simple-boilerplate",
"version": "1.0.0",
"description": "Simple and lightweight Boilerplate for ReactJS projects",
"scripts": {
"lint": "eslint src",
"start": "node server.js",
"test": "jest"
},
"devDependencies": {
"babel-core": "^6.24.1",
"babel-loader": "^7.0.0",
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"css-loader": "^0.28.0",
"enzyme": "^3.2.0",
"enzyme-adapter-react-16": "^1.1.0",
"eslint": "^3.19.0",
"eslint-plugin-react": "^6.10.3",
"jest": "^21.2.1",
"node-sass": "^4.5.2",
"react-addons-test-utils": "^15.6.2",
"sass-loader": "^6.0.3",
"style-loader": "^0.16.1",
"webpack": "^2.4.1",
"webpack-dev-server": "^2.4.4"
},
"dependencies": {
"babel-loader": "^7.0.0",
"react": "^15.5.4",
"react-dom": "^15.5.4"
},
"main": "server.js"
}
Have no idea why its giving me this message?
It looks like babel-jest is missing among your dependencies. That's why jest is not running babel on your ES6+ code before executing tests.
I'm pretty sure you need to add your babel presets to test as well, jest sets the env variable to test.
So...
"test": {
"plugins": ["transform-es2015-modules-commonjs"],
"presets": ["es2015", "react", "stage-0"]
}

Failing in integrating tests in my react app using jest

I am trying to setup react app for enzyme + jest testing but getting error on yarn test
My package.json is
{
"scripts": {
"start": "webpack-dev-server --hot --open",
"build": "webpack --config ./webpack.production.config.js --progress --profile --colors",
"precommit": "lint-staged",
"format": "prettier --fix --write \"app/**/*.{js,jsx,json,css,scss}\"",
"test": "jest"
},
"jest": {
"moduleNameMapper": {
"^config$": "<rootDir>/jest.config.js"
}
},
"license": "MIT",
"dependencies": {
"#types/react": "^16.3.16",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-polyfill": "^6.26.0",
"react": "^16.3.2",
"react-slick": "^0.24.0",
"enzyme": "^3.10.0",
"enzyme-adapter-react-16": "^1.14.0",
},
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-jest": "^23.6.0",
"babel-loader": "^7.1.4",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"babel-polyfill": "^6.16.0",
"husky": "^0.14.3",
"jest": "^23.4.2",
"jest-cli": "^23.6.0",
"jest-enzyme": "^7.0.2",
"webpack": "^4.6.0",
"webpack-cli": "^2.1.2",
"webpack-dev-server": "^3.1.1"
}
}
And my setupTests.js. I found this on github
global.matchMedia =
global.matchMedia ||
function() {
return {
matches: false,
addListener() {},
removeListener() {},
};
};
I have jest.config.js to
module.exports = {
moduleFileExtensions: ['js', 'jsx', 'json'],
transform: {
'^.+\\.(js|jsx)?$': 'babel-jest',
},
transformIgnorePatterns: ['<rootDir>/node_modules/'],
};
Any idea how to solve the issue ? I have search a lot but find nothing.
In setupTests.js put
window.matchMedia = window.matchMedia || function() {
return {
matches : false,
addListener : function() {},
removeListener: function() {}
};
};
stop all tasks and then run npm test. SHould work now.
link

Cannot resolve stream dependency of styled components

I'm stuck with adding styled-components library into my reactjs project. I'm getting an error when trying to run my app in browser, not at the building stage. It's quite common:
Here is my webpack config:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
context: path.join(__dirname, 'src'),
entry: {
server: '../server/index.js',
app: './app.jsx',
},
resolve: {
extensions: ['.jsx', '.js'],
},
module: {
rules: [
{
test: /\.(jsx|js)?$/,
use: {
loader: 'babel-loader',
},
},
],
},
target: 'node',
plugins: [
new HtmlWebpackPlugin({
template: './index.html',
filename: './index.html',
excludeChunks: ['server'],
}),
],
};
Here is my babelrc:
{
"presets": ["#babel/preset-env", "#babel/preset-react"],
"plugins": [
"#babel/plugin-transform-runtime",
"babel-plugin-styled-components"
]
}
Here is my styled component:
import React from 'react';
import styled from 'styled-components';
export function SearchPage() {
const Container = styled.div`
text-align: center;
`;
return <Container>test</Container>;
}
Here is my package.json:
{
"devDependencies": {
"#babel/core": "^7.3.4",
"#babel/plugin-transform-runtime": "^7.4.0",
"#babel/preset-env": "^7.3.4",
"#babel/preset-react": "^7.0.0",
"babel-eslint": "^10.0.1",
"babel-loader": "^8.0.5",
"babel-plugin-styled-components": "^1.10.0",
"enzyme": "^3.9.0",
"enzyme-adapter-react-16": "^1.11.2",
"eslint": "^5.15.3",
"eslint-config-airbnb-base": "^13.1.0",
"eslint-config-prettier": "^4.1.0",
"eslint-plugin-import": "^2.16.0",
"eslint-plugin-prettier": "^3.0.1",
"eslint-plugin-react": "^7.12.4",
"eslint-plugin-react-hooks": "^1.6.0",
"husky": "^1.3.1",
"jest": "^24.5.0",
"live-server": "^1.2.1",
"nodemon": "^1.18.10",
"npm-run-all": "^4.1.5",
"prettier": "^1.16.4",
"react-redux": "^6.0.1",
"react-router": "^4.4.0",
"redux": "^4.0.1",
"rimraf": "^2.6.3",
"stream": "^0.0.2",
"uglifyjs-webpack-plugin": "^2.1.2",
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3"
},
"version": "1.0.0",
"main": "dist/server.js",
"scripts": {
"clean": "rimraf dist build",
"dev": "npm-run-all -p dev:watch server:run dev:server",
"dev:build": "webpack --config webpack.dev.js",
"dev:watch": "yarn run dev:build --watch",
"dev:server": "live-server dist",
"server:run": "nodemon",
"prod:build": "npm-run-all clean webpack --config webpack.prod.js",
"test": "jest"
},
"dependencies": {
"express": "^4.16.4",
"html-webpack-plugin": "^3.2.0",
"webpack-merge": "^4.2.1",
"react": "^16.8.4",
"react-dom": "^16.8.4",
"styled-components": "^4.2.0"
}
}
I thought that Webpack should bundle all the dependencies. And I don't understand why stream import is not covered by webpack bundling.
I guess that the answer is pretty simple, but I cannot find it. So any advice will be helpful.
The thing is in target: 'node' into my package.json. It's supposed to use only for server-side build not for client.

Resources