I'm learning to write a test for my react typescript app and come across this problem. I tried to use many different methods I found on internet but nothing work, the error is
Test suite failed to run
ReferenceError: expect is not defined
at Object.<anonymous> (node_modules/#testing-library/jest-dom/dist/extend-expect.js:7:1)
at Object.<anonymous> (node_modules/#testing-library/jest-dom/extend-expect.js:2:1)
This is my App.test.tsx file. Where error occur.
import React from 'react';
import App from './App';
import {render, fireEvent, waitFor, screen} from '#testing-library/react'
import "#testing-library/jest-dom/extend-expect";
import '#testing-library/jest-dom'
test('renders learn react link',async () => {
let screen = render(<App></App>);
expect(screen.getByText(/Hello/i)).toBeInTheDocument()
});
My package.json file
{
"dependencies": {
"#emotion/react": "^11.7.1",
"#emotion/styled": "^11.6.0",
"#fontsource/roboto": "^4.5.1",
"#mui/material": "^5.2.7",
"#testing-library/jest-dom": "^4.2.4",
"#testing-library/react": "^12.1.2",
"#testing-library/user-event": "^7.1.2",
"#types/jest": "^27.4.0",
"#types/node": "^17.0.8",
"#types/react": "^17.0.38",
"#types/react-dom": "^17.0.11",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-scripts": "3.4.1",
"ts-jest": "^27.1.2",
"typescript": "^4.5.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"devDependencies": {
"#babel/preset-env": "^7.16.7",
"#babel/preset-react": "^7.16.7",
"babel-jest": "^27.4.6",
"jest": "^27.4.7",
"react-test-renderer": "^17.0.2"
}
}
And these are my jest.config.js and bebel.config.js file (Not sure if this matter)
module.exports = {
roots: ["<rootDir>/src"],
testMatch: [
"**/__tests__/**/*.+(ts|tsx|js)",
"**/?(*.)+(spec|test).+(ts|tsx|js)",
],
transform: {
"^.+\\.(ts|tsx)$": "ts-jest",
},
coveragePathIgnorePatterns: [
"/node_modules/"
],
moduleNameMapper: {
"\\.(css|less)$": "identity-obj-proxy",
},
"setupFiles": [
"<rootDir>/src/setupTests.ts"
]
};
module.exports = function (api) {
const presets = [
'#babel/preset-env',
'#babel/preset-react',
'#babel/preset-flow'
];
const plugins = [
'#babel/plugin-transform-runtime',
];
api.cache(false);
return {
presets,
plugins
};
};
delete node_modules directory and do npm install
also replace the "setupFiles" with setupFilesAfterEnv in jest.config.js like following
setupFilesAfterEnv: [
'./setupTests.js',
],
try this in App.test.tsx
import React from 'react';
import App from './App';
import {render, fireEvent, waitFor, screen} from '#testing-library/react'
test('renders learn react link',async () => {
let screen = render(<App/>);
expect(screen.getByText(/Hello/i)).toBeInTheDocument()
});
Related
Trying to import { GoogleSpreadsheet } from 'google-spreadsheet' in my React App but getting this nasty error
Uncaught ReferenceError: process is not defined
at loadProxy (gaxios.ts:66:5)
at node_modules/gaxios/build/src/gaxios.js (gaxios.ts:75:1)
at __require (chunk-RSJERJUL.js?v=0db569af:3:50)
at node_modules/gaxios/build/src/index.js (index.ts:15:1)
at __require (chunk-RSJERJUL.js?v=0db569af:3:50)
at node_modules/gcp-metadata/build/src/index.js (index.ts:8:1)
at __require (chunk-RSJERJUL.js?v=0db569af:3:50)
at node_modules/google-auth-library/build/src/auth/googleauth.js (googleauth.js:19:21)
at __require (chunk-RSJERJUL.js?v=0db569af:3:50)
at node_modules/google-auth-library/build/src/index.js (index.js:17:22)
here below is a screenshot of my current app structure that I have started using Vite (which maybe is why this is not working?)
package.json
{
"name": "tinder-triage",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"google-spreadsheet": "^3.3.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"#types/react": "^18.0.27",
"#types/react-dom": "^18.0.10",
"#vitejs/plugin-react": "^3.1.0",
"vite": "^4.1.0"
}
}
vite.config.js
import { defineConfig } from 'vite'
import react from '#vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
})
I am writing tests for React component with #testing-library/react and vitest. Here is my code:
It works fine, but for some reason I get these annoying warnings:
When I rewrite code to this:
then the test fails:
This problem also occurs with other components (although the test doesn't fail):
My imports look like this:
I would like to understand why this is happening and how to fix it. I saw a similar question asked here before, but the solutions recommended there didn't help me.
App.test.jsx
import {screen} from "#testing-library/react";
import {describe, expect} from "vitest";
import App from "#components/App/App";
import {renderWithProviders} from "#utils/utils-for-tests/renderWithProwiders";
describe('App', () => {
it('Renders App', () => {
renderWithProviders(<App />);
expect(screen.getByRole('banner')).toBeInTheDocument()
expect(screen.getByRole('main').toBeInTheDocument)
expect(screen.getByRole('contentinfo').toBeInTheDocument)
});
});;
Header.test.jsx
import {describe, expect} from "vitest";
import {renderWithProviders} from "#utils/utils-for-tests/renderWithProwiders";
import Header from "#components/Header/Header";
import {MemoryRouter} from "react-router-dom";
import {waitFor,screen} from "#testing-library/react";
import userEvent from "#testing-library/user-event";
describe('Header', () => {
it('check search', async ()=>{
renderWithProviders(<MemoryRouter><Header/></MemoryRouter>)
const input = screen.getByPlaceholderText(/Search here.../i)
await userEvent.type(input, "Test");
await waitFor(()=>{
expect(input).toHaveValue("Test")
})
await userEvent.click(screen.getByRole('button',{name: /search-submit/i}));//should reset input field
await waitFor(()=>{
expect(input).not.toHaveValue("Test")
})
})
});
setup.js for vitest
import { expect, afterEach } from 'vitest';
import { cleanup } from '#testing-library/react';
import matchers from '#testing-library/jest-dom/matchers';
// extends Vitest's expect method with methods from react-testing-library
expect.extend(matchers);
// runs a cleanup after each test case (e.g. clearing jsdom)
afterEach(() => {
cleanup();
});
vite.config.js
import { defineConfig } from 'vite'
import react from '#vitejs/plugin-react-swc'
import eslint from 'vite-plugin-eslint'
const path = require('path')
// https://vitejs.dev/config/
export default defineConfig({
resolve:{
alias:{
'#' : path.resolve(__dirname, './src'),
'#components' : path.resolve(__dirname, './src/components'),
'#pages' : path.resolve(__dirname, './src/pages'),
'#assets' : path.resolve(__dirname, './src/assets'),
'#hooks' : path.resolve(__dirname, './src/hooks'),
'#store' : path.resolve(__dirname, './src/store'),
'#slices' : path.resolve(__dirname, './src/store/slices'),
'#fonts' : path.resolve(__dirname, './src/assets/fonts'),
'#utils' : path.resolve(__dirname, './utils'),
},
},
plugins: [react(),eslint()],
test: {
globals: true,
environment: 'jsdom',
setupFiles: './tests/setup.js',
coverage: {
reporter: ['text', 'json', 'html'],
}
},
})
package.json
{
"name": "e-commerce",
"private": true,
"version": "0.0.0",
"scripts": {
"dev": "vite --open",
"build": "vite build",
"test": "vitest --ui",
"coverage": "vitest run --coverage",
"preview": "vite preview"
},
"eslintConfig": {
"extends": [
"plugin:react-hooks/recommended",
"react-app"
],
"parserOptions": {
"sourceType": "module",
"ecmaVersion": 2020,
"ecmaFeatures": {
"jsx": true
}
}
},
"dependencies": {
"#reduxjs/toolkit": "^1.9.1",
"firebase": "^9.15.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.41.3",
"react-redux": "^8.0.5",
"react-router-dom": "^6.6.1",
"redux": "^4.2.0",
"sass": "^1.57.1"
},
"devDependencies": {
"#testing-library/jest-dom": "^5.16.5",
"#testing-library/react": "^13.4.0",
"#testing-library/user-event": "^14.4.3",
"#types/react": "^18.0.26",
"#types/react-dom": "^18.0.9",
"#vitejs/plugin-react-swc": "^3.0.0",
"#vitest/ui": "^0.26.3",
"classnames": "^2.3.2",
"eslint": "^8.31.0",
"eslint-config-react-app": "^7.0.1",
"eslint-plugin-react-hooks": "^4.6.0",
"jsdom": "^21.0.0",
"vite": "^4.0.0",
"vite-plugin-eslint": "^1.8.1",
"vitest": "^0.26.3"
}
}
I found the solution. I don't need to import {describe, expect} from 'vitest'
I am trying to test my application.
The test that I am trying to run, has as objective to test a thunk function (redux toolkit).
I am also using Firebase for authentication and Firestore for storage.
I have this error in console.
Jest encountered an unexpected token
/home/fml/Escritorio/Projects/Journal-app/node_modules/firebase/app/dist/index.esm.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import { registerVersion } from '#firebase/app';
^^^^^^
SyntaxError: Cannot use import statement outside a module
> 1 | import { FirebaseOptions, initializeApp } from 'firebase/app';
| ^
2 | import { getAuth } from 'firebase/auth';
3 | import { getFirestore } from 'firebase/firestore/lite';
4 | import { getEnvironments } from '../utils';
at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1796:14)
at Object.<anonymous> (src/firebase/config.ts:1:1)
This is the test I am trying to run. I am trying to mock my providers file, which consists of Firebase authentication methods, but it doesn't seem to work.
import { checkingCredentials } from '../../../src/redux/auth/authSlice';
import { checkingAuthentication } from '../../../src/redux/auth/thunk';
jest.mock('../../../src/firebase/providers');
describe('thunk.ts (auth)', () => {
const dispatch = jest.fn();
beforeEach( () => jest.clearAllMocks() );
test('should invoke checkingCredentials', async() => {
await checkingAuthentication()( dispatch );
expect( dispatch ).toHaveBeenCalledWith( checkingCredentials() )
});
});
This is my jest config (jest.config.ts):
export default {
testEnvironment: "jsdom",
transform: {
"^.+\\.tsx?$": "ts-jest"
},
moduleNameMapper: {
'\\.(css|less|sass|scss)$': 'identity-obj-proxy',
},
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
transformIgnorePatterns: [],
}
This is my jest setup (jest.setup.ts):
import 'setimmediate';
import 'whatwg-fetch';
import { config } from 'dotenv';
config({
path: '.env'
});
jest.mock('./src/utils/getEnvironments', () => ({
getEnvironments: () => ({ ...process.env })
}));
Main Stack:
Vite JS: 2.9.9
React JS: 18.0.0
TypeScript: 4.6.3
Firebase: 9.8.3
reduxjs/toolkit: 1.8.2
These are my installed dependencies
{
"name": "journal-app",
"private": true,
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"test": "jest --verbose=true"
},
"dependencies": {
"#cloudinary/react": "^1.4.1",
"#cloudinary/url-gen": "^1.8.0",
"#lottiefiles/react-lottie-player": "^3.4.7",
"#reduxjs/toolkit": "^1.8.2",
"firebase": "^9.8.3",
"react": "18.0.0",
"react-dom": "18.0.0",
"react-hot-toast": "^2.2.0",
"react-icons": "^4.4.0",
"react-redux": "^8.0.2",
"react-router-dom": "^6.3.0"
},
"devDependencies": {
"#testing-library/react": "^13.3.0",
"#types/jest": "^28.1.2",
"#types/react": "18.0.0",
"#types/react-dom": "18.0.0",
"#types/react-redux": "^7.1.24",
"#vitejs/plugin-react": "1.3.0",
"autoprefixer": "10.4.7",
"cloudinary": "^1.30.0",
"daisyui": "2.15.4",
"dotenv": "^16.0.1",
"identity-obj-proxy": "^3.0.0",
"jest": "^28.1.1",
"jest-environment-jsdom": "^28.1.1",
"postcss": "8.4.14",
"setimmediate": "^1.0.5",
"tailwindcss": "3.1.3",
"ts-jest": "^28.0.5",
"ts-node": "^10.8.1",
"typescript": "4.6.3",
"vite": "2.9.9",
"whatwg-fetch": "^3.6.2"
}
}
How can I mock my file or how can I test the thunk function?
I'm trying to test a react component using both jest and enzyme, i've installed the necessary package for them, then configured my setupTests.js as shown below, but still have the same error that Enzyme module is not found, and "shallow" as well.
this is where i am trying to use Shallow from enzyme
import React from "react";
import { render, screen, cleanup } from '#testing-library/react'
import { shallow } from "#wojtekmaj/enzyme-adapter-react-17"
//some necessary local imports
// some other tests
describe('Welcome Component', () => {
it('renders Button component', () => {
const wrapper = shallow(<Welcome />);
expect(wrapper.containsMatchingElement(<NextButton text={"Next"}/>)).toEqual(true);
});
});
this is my setupTests.js
import '#testing-library/jest-dom';
import enzyme from 'enzyme';
import Adapter from '#wojtekmaj/enzyme-adapter-react-17';
enzyme.configure({ adapter: new Adapter() });
and here is my package.json
{
"name": "react-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"#emotion/react": "^11.7.0",
"#emotion/styled": "^11.6.0",
"#fontsource/rubik": "^4.5.0",
"#material-ui/core": "^4.12.3",
"#mui/core": "^5.0.0-alpha.54",
"#mui/material": "^5.2.3",
"#reduxjs/toolkit": "^1.6.2",
"#testing-library/jest-dom": "^5.11.4",
"#testing-library/react": "^11.1.0",
"#testing-library/user-event": "^12.1.10",
"#types/react": "^17.0.33",
"ajv": "^8.8.2",
"axios": "^0.24.0",
"bootstrap": "^5.1.3",
"enzyme": "^3.11.0",
"formik": "^2.2.9",
"fs": "0.0.1-security",
"icomoon-react": "^2.0.19",
"jest": "^27.4.5",
"jodit-react": "^1.1.11",
"js-file-download": "^0.4.12",
"lodash": "^4.17.21",
"lodash-redux-immutability": "0.0.3",
"popper.js": "^1.16.1",
"react": "^17.0.2",
"react-bootstrap": "^2.0.0",
"react-contenteditable": "^3.3.6",
"react-dom": "^17.0.2",
"react-icons": "^4.3.1",
"react-lottie": "^1.2.3",
"react-redux": "^7.2.6",
"react-router-dom": "^6.0.2",
"react-scripts": "4.0.3",
"react-split": "^2.0.13",
"react-split-pane": "^0.1.92",
"react-toast-notifications": "^2.5.1",
"react-web-vector-icons": "^1.0.2",
"redux-persist": "^6.0.0",
"redux-subscriber": "^1.1.0",
"reselect": "^4.1.5",
"web-vitals": "^1.0.1",
"xml2js": "^0.4.23",
"yup": "^0.32.11"
},
"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"
]
},
"devDependencies": {
"#wojtekmaj/enzyme-adapter-react-17": "^0.6.6",
"sass": "^1.43.2",
"sass-loader": "^12.2.0"
}
}
Install all these dependencies in dev. In my case I am using typescript, if
you are using javascript, skip types. Run npm i -D and all these
dependencies.
#types/enzyme
#types/enzyme-adapter-react-16
enzyme
enzyme-adapter-react-16
jest-environment-enzyme
jest-enzyme
#testing-library/jest-dom
#testing-library/react
#testing-library/user-event
#types/jest
ts-jest
In root of your project, create a file named jest.config.js and inside put this code :
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
modulePathIgnorePatterns: ["/dist/"],
};
In the same root of the project, create a file called jest.config.unit.js and put this code there:
module.exports = {
preset: 'ts-jest',
testEnvironment: 'jsdom',
modulePathIgnorePatterns: ["<rootDir>/dist/"],
setupFilesAfterEnv: ["jest-enzyme"],
setupFiles: ['<rootDir>/src/setupEnzyme.ts'],
// ignore .js files
testRegex: '(/__tests__/.*|(\\.|/)(test))\\.[t]sx?$',
coverageReporters: ["lcov", "text"],
coverageDirectory: "test-coverage",
coverageThreshold: {
global: {
branches: 0,
functions: 0,
lines: 0,
statements: 0
}
}
};
Go to src folder, and create this file: setupEnzyme.ts(js), inside put this code:
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure({ adapter: new Adapter() });
In src folder, create a file setupTests.ts(js) and put this code inside:
import '#testing-library/jest-dom';
Finally go to package.json, and under the scripts add this
"test": "jest -c jest.config.unit.js",
You are all set up. Create some test component, like Test.js which returns a simple div. Create a correspondent Test.test.js and add this test code:
import { shallow } from 'enzyme';
import { Test } from './test';
describe('<Test /> renders correctly', () => {
it('Renders correctly', () => {
const wrapper = shallow(<Test />);
expect(wrapper).toMatchSnapshot();
});
});
And if you run npm run test it should work.
I want to use enzyme to perform unit tests in my React project with TypeScript.
I used documentation on adding tests to create-react-app - runnning tests
I created a setupTests.ts file in /src
setupTests.ts
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure({ adapter: new Adapter() });
And I wrote a test
App.test.ts
import React from 'react';
import { shallow } from 'enzyme';
import App from './App';
it('renders without crashing', () => {
shallow(<App />);
});
A test using react-dom works fine if I comment the line which configures adapter in setupTests.ts
setupTests.ts
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
// configure({ adapter: new Adapter() });
App.test.ts
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/Dashboard';
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<App />, div);
});
package.json
{
"name": "sampleapp",
"version": "0.1.0",
"private": true,
"dependencies": {
"#material-ui/core": "^3.9.2",
"#material-ui/icons": "^3.0.2",
"#types/enzyme": "^3.9.1",
"#types/enzyme-adapter-react-16": "^1.0.5",
"#types/enzyme-to-json": "^1.5.3",
"#types/jest": "24.0.11",
"#types/node": "11.12.0",
"#types/react": "16.8.8",
"#types/react-dom": "16.8.3",
"#types/react-redux": "^7.0.5",
"#types/react-router-dom": "^4.3.1",
"#types/redux-thunk": "^2.1.0",
"axios": "^0.18.0",
"react": "^16.8.5",
"react-dom": "^16.8.5",
"react-redux": "^6.0.1",
"react-router-dom": "^5.0.0",
"react-scripts": "2.1.8",
"redux": "^4.0.1",
"redux-thunk": "^2.3.0",
"typescript": "3.3.4000"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}
The test is supposed to run successfully. But it is failing and giving me an error
Cannot find module 'enzyme' from 'setupTests.ts'
You should do yarn add enzyme and you'll be good!
Or npm i enzyme if you're using npm.
#types/enzyme is used to get typescript interfaces but not the actual enzyme package!