I got jest working on my react app and I'm trying to run tests, but I'm getting an error. When I run the test with "scripts": {"test": "react-scripts test --env=jsdom"} almost every test works. I had to change my tester to "test":"jest" to get the last test working, but now the test are crashing on compile because the < in the multiple shallow(<ReactPage />) is throwing an error.
From my understanding of the code, my test should be fine. Should be some setting for jest that I have to make in the project.json file to fix this error?
Test
import {shallow, mount, configure} from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import ReactDOM from 'react-dom';
import jest from 'jest';
import ReactPage from './App';
configure({ adapter: new Adapter() });
it('renders ReactPage without crashing', () => {
const div = document.createElement('div');
ReactDOM.render( <ReactPage /> , div);
ReactDOM.unmountComponentAtNode(div);
});
package.json
{
"name": "client-charts",
"version": "0.1.0",
"private": true,
"dependencies": {
"async": "^2.6.1",
"moment": "^2.22.2",
"react": "^16.4.2",
"react-dom": "^16.4.1",
"react-scripts": "1.1.4",
"recharts": "^1.1.0",
"react-table": "^6.8.6",
"react-snapshot": "^1.3.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build && react-snapshot",
"test": "jest",
"eject": "react-scripts eject"
},
"proxy": "http://localhost:5000",
"devDependencies": {
"enzyme": "^3.3.0",
"enzyme-adapter-react-16": "^1.1.1",
"jest": "^20.0.4"
}
}
You are missing a step to process the JSX. If you are using babel, add a react preset to your .babelrc file. More info can be found here: https://jestjs.io/docs/en/getting-started#additional-configuration
Related
Many articles and tutorials teach how to share components in monorepo projects.
But they show something in an unproductive way.
Share each component (package1, package2) separately in workspace. What I intend to do is export a complete package using atomic design, coming from a ui package only.
But when trying to do this this error is generated
I'm importing this way
import { Button } from 'ui/atoms'
package.json
{
"name": "ui",
"version": "0.0.0",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"license": "MIT",
"scripts": {
"dev": "tsc --watch --outDIr dist",
"build": "tsc --outDir dist",
"lint": "eslint *.ts*"
},
"devDependencies": {
"#types/react": "^18.0.17",
"#types/react-dom": "^18.0.6",
"eslint": "^7.32.0",
"eslint-config-custom": "workspace:*",
"react": "^18.2.0",
"tsconfig": "workspace:*",
"typescript": "^4.5.2"
}
}
Using import from "ui" it works, that is, we would have to keep creating files like Button.tsx and importing them in the ui index and using them in the project, but it is inefficient, imagine thousands of components (atoms, molecules).
import * as React from "react";
export * from "./Button";
I think I'll have to share other config files, so I'll be willing to change the post and put them.
App.tsx - Importing ui
import React from 'react';
import './App.css';
import { Button } from 'ui/atoms'
function App() {
return (
<div className="App">
<Button/>
</div>
);
}
export default App;
package.json
{
"name": "main_",
"version": "0.1.0",
"private": true,
"dependencies": {
"#testing-library/jest-dom": "^5.16.5",
"#testing-library/react": "^13.4.0",
"#testing-library/user-event": "^13.5.0",
"#types/jest": "^27.5.2",
"#types/node": "^16.18.3",
"#types/react": "^18.0.25",
"#types/react-dom": "^18.0.9",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"typescript": "^4.9.3",
"web-vitals": "^2.1.4",
"tsconfig":"workspace:*",
"ui":"workspace:*"
},
"scripts": {
"dev": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
link to the repository
micro-frontend
Ui library is being used in "apps/main_/src/App.tsx
After a while without messing with monorepo, I came back these days and found the solution for it.
Let's go to the problem I reported, and considered unfeasible.
Many monorepo projects using Turbo using component sharing as follows.
//index.tsx
export { Avatar, AvatarGroup } from "./components/avatar";
export type { AvatarProps, AvatarGroupProps } from "./components/avatar";
export { Badge, UpgradeTeamsBadge } from "./components/badge";
export type { BadgeProps } from "./components/badge";
export { Breadcrumb, BreadcrumbContainer, BreadcrumbItem } from "./components/breadcrumb";
export { Button, LinkIconButton } from "./components/button";
export type { ButtonBaseProps, ButtonProps } from "./components/button";
export { ButtonGroup } from "./components/buttonGroup";
export {
Checkbox,
EmailField,
EmailInput,
FieldsetLegend,
DropdownMenuLabel,
Steps,
WizardForm,
SettingsToggle,
Stepper,
Switch,
} from "./components/form";
Realize that you have to keep importing all your components in the index, so that you can use them in other projects.
Correction
To resolve, just add the other files to eslint
"scripts": {
"lint": "eslint *.ts* atoms/**"
},
With that there will be no need to import all the components in the index, in fact, you don't even need to have it
I'm currently working on a MERNG app, and i was doing the setup in the fronted, and, when i ran npm run start, this error suddenly appeared
Error from chokidar (C:\): Error: EBUSY: resource busy or locked, lstat 'C:\hiberfil.sys'
Compiling...
i've searched for this problem, and i found that, you should delete node_modules, then run npm intall, i tried, didn't work
This is my package.json
{
"name": "client",
"version": "0.1.0",
"private": true,
"dependencies": {
"#apollo/client": "^3.3.14",
"#testing-library/jest-dom": "^5.11.10",
"#testing-library/react": "^11.2.6",
"#testing-library/user-event": "^12.8.3",
"apollo-link-context": "^1.0.20",
"framer-motion": "^4.1.3",
"moment": "^2.29.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-file-base64": "^1.0.3",
"react-redux": "^7.2.3",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.3",
"redux": "^4.0.5",
"styled-components": "^5.2.3",
"styled-icons": "^10.33.0",
"web-vitals": "^1.1.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
This is my index, i put there my apolloProvider and my redux setup
import React from "react";
import ReactDOM from "react-dom";
import ApolloProvider from "./ApolloProvider";
import { Provider } from "react-redux";
import { createStore } from "redux";
import { reducer } from "./reducer";
const store = createStore(reducer);
ReactDOM.render(
<Provider store={store}>{ApolloProvider}</Provider>,
document.getElementById("root")
);
This is my apollo provider
import React from "react";
import {
ApolloClient,
InMemoryCache,
ApolloProvider,
createHttpLink
} from "#apollo/client";
import App from "./App";
const httpLink = new createHttpLink({
uri: "http://localhost:5000"
});
const client = new ApolloClient({
link: httpLink,
cache: new InMemoryCache()
});
export default (
<ApolloProvider client={client}>
<App />
</ApolloProvider>
);
What is going on with my react app? i'm mad at this because it came out of nowhere, any clue how to fix this? And thank your four time comunnity !
I don't know why i get empty shallowWrapper object when i run snapshot test, i am using Jest and Enzyme:
What i get in App.test.js.snap file:
// Jest Snapshot v1, "goo.gl/fbAQLP"
exports[`renders App component 1`] = `ShallowWrapper {}`;
my package.json file:
{
"name": "test",
"version": "0.1.0",
"private": true,
"dependencies": {
"#fortawesome/fontawesome-svg-core": "^1.2.30",
"#fortawesome/free-solid-svg-icons": "^5.14.0",
"#fortawesome/react-fontawesome": "^0.1.11",
"#testing-library/jest-dom": "^4.2.4",
"#testing-library/react": "^9.3.2",
"#testing-library/user-event": "^7.1.2",
"bootstrap": "^4.5.2",
"install": "^0.13.0",
"npm": "^6.14.8",
"react": "^16.13.1",
"react-bootstrap": "^1.3.0",
"react-dom": "^16.13.1",
"react-router-dom": "^5.2.0",
"react-scripts": "^4.0.0-next.98"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.4",
"jest": "^26.4.2"
}
}
App.test.js file
import { shallow } from 'enzyme';
import React from 'react';
import App from './App';
it('renders App component', () => {
expect(shallow(<App />)).toMatchSnapshot();
})
setupTests.js file:
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure({
adapter: new Adapter()
});
Why i get that empty shallowWrapper object, I suspected the version of jest after some search, but even downgrading didn't solve it.
I ran into similar problem and playing around with jest help me got through it. I suggest you can clear the jest cache and then update the snapshots using jest --clearCache && jest -u and then run your test.
Also for your snapshot, I'd recommend you to use enzyme-to-json serialiser (https://www.npmjs.com/package/enzyme-to-json) and modify your test to:
import { shallow } from 'enzyme';
import React from 'react';
import App from './App';
import { shallowToJson } from 'enzyme-to-json';
it('renders App component', () => {
const app = shallow(<App />);
expect(shallowToJson(app)).toMatchSnapshot();
})
The shallow( ) did returned the output. Shallow works as a wrapper instance with the rendered output. You could use shallow( ) method with debug( ) to see what prints out. If you want to see the rendered output,you could use shallow().html( ) inside the expect( ) method to test again.
I'm trying to use jest.spyOn() for my tests instead of jest.mock since the return value of a mock can't be type-checked. When I use it though, I get the following error:
TypeError: Cannot set property useGame of #<Object> which has only a getter
> 3 | const STATE_SPY = jest.spyOn(hooks, "useGame");
| ^
at ModuleMockerClass.spyOn (node_modules/jest-mock/build/index.js:852:26)
at Object.<anonymous> (src/components/game/game.test.tsx:4:24)
My files are structured like:
src/
- game.test.tsx
- game.tsx
- hooks/
- index.tsx
- use-game.tsx
And here is how my code is laid out (I removed a lot of extraneous code for this question
to make it easier to read).
/hooks/index.tsx:
export { default as useGame } from "./use-game";
use-game.tsx:
export default function useGame(initScore: number) {
const [score, setScore] = useState(initScore);
return {
score,
setScore,
}
}
game.test.tsx:
import * as hooks from "./hooks";
const STATE_SPY = jest.spyOn(hooks, "useGame");
game.tsx:
import React from "react";
import { useGame } from "./hooks";
const STARTING_SCORE = 50;
export default function Game(): JSX.Element {
const {score} = useGame(STARTING_SCORE);
return (
<div>
{score}
</div>
)
}
I think the issue is how useGame is exported as a module. But I haven't figured out a way to export/import it "correctly". Of course, there could be another issue that I'm unaware of.
App was created with create-react-app.
My package.json in case that helps.
{
"name": "greatest-game-of-all-time",
"version": "0.1.0",
"private": true,
"dependencies": {
"#material-ui/core": "^4.11.0",
"#material-ui/icons": "^4.9.1",
"#types/jest": "^24.9.1",
"#types/node": "^12.12.53",
"#types/react": "^16.9.43",
"#types/react-dom": "^16.9.8",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-hook-form": "^6.1.2",
"react-scripts": "^3.4.1",
"typescript": "^3.9.7"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"#testing-library/dom": "^7.21.5",
"#testing-library/jest-dom": "^4.2.4",
"#testing-library/react": "^9.5.0",
"#testing-library/react-hooks": "^3.4.1",
"#testing-library/user-event": "^7.2.1",
"prettier": "2.0.5",
"react-test-renderer": "^16.13.1"
}
}
I looked through your package.json and noticed that the package #testing-library/react-hooks had been added earlier. I propose to use it in order to write new tests for hooks.
You can read the documentation to get started https://github.com/testing-library/react-hooks-testing-library
It seems you use babel to transpile your code. As I know that if you import with wild card (namespace) like that. It will create a object contains your named exports as getter like
var obj = { get namedExport: () => ... }
so in this case, I suggest to either mock entire module:
jest.mock('./hooks', () => ({ useGame: yourMock }))
or switch to tsc by using ts-jest to fix your issue (since tsc won't use getter to export that named export)
I have a create-react-app project and trying to unit test office-ui-fabric-react component using Jest and Enzyme.
The latest version of office-ui-fabric-react use es6 syntax and jest is failing to run the test.
import { mount } from "enzyme";
import React from "react";
import { MessageBar, MessageBarType } from "office-ui-fabric-react/lib/MessageBar";
describe("<MessageBar />", () => {
it("renders message bar correctly", () => {
const wrapper = mount(<MessageBar messageBarType={MessageBarType.success} />);
expect(wrapper.find('.ms-MessageBar--success').length).toEqual(1);
});
});
This is the package.json file coming from create-react-app with few additions
{
"name": "test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"office-ui-fabric-react": "^6.110.1",
"react": "^16.6.3",
"react-dom": "^16.6.3",
"react-scripts": "2.1.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"devDependencies": {
"#types/enzyme": "3.1.5",
"#types/enzyme-adapter-react-16": "1.0.1",
"#types/jest": "23.0.0",
"#types/react": "16.3.16",
"#types/react-dom": "16.0.5",
"#types/react-test-renderer": "^16.0.0",
"enzyme": "^3.7.0",
"enzyme-adapter-react-16": "^1.7.0",
"jest": "^23.6.0"
}
}
Error
create-react-app is not allowing me to specify ani options for jest in package.json without ejecting.
After looking at the suggestions in the comments above, the following set worked for me:
{
"name": "test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"office-ui-fabric-react": "^6.110.1",
"react": "^16.6.3",
"react-dom": "^16.6.3",
"react-scripts": "2.1.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"devDependencies": {
"babel-core": "^7.0.0-bridge.0",
"babel-jest": "^23.6.0",
"enzyme": "^3.7.0",
"enzyme-adapter-react-16": "^1.7.0",
"jest": "^23.6.0"
}
}
In my test file sample-tests.jsx
import Enzyme from "enzyme";
import { mount } from "enzyme";
import React from "react";
import { MessageBar, MessageBarType } from "office-ui-fabric-react/lib-commonjs/MessageBar";
import Adapter from 'enzyme-adapter-react-16';
Enzyme.configure({ adapter: new Adapter() });
describe("<MessageBar />", () => {
it("renders message bar correctly", () => {
const wrapper = mount(<MessageBar messageBarType={MessageBarType.success} />);
expect(wrapper.find('.ms-MessageBar--success').length).toEqual(1);
});
});