-
Packages to install to work with javascript
yarn add -D @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript jest babel-jest @types/jest @testing-library/react @testing-library/dom @testing-library/jest-dom @testing-library/user-event jest-environment-jsdom react-test-renderer
-
Packages to install to work with typescript
yarn add -D jest-css-modules jest-transform-stub ts-jest ts-node
-
If use Fetch API, install this polyfill for it (Optional)
yarn add -D whatwg-fetch
-
Update the scripts
package.json
"scripts: { ... "test": "jest --watchAll --detectOpenHandles"
-
Crear la configuración de babel babel.config.js or babel.config.cjs (RECOMENDED)
//babel.config.js export default { presets: [ ['@babel/preset-env', {targets: {esmodules: true, node: 'current'}}], ['@babel/preset-react', {runtime: 'automatic'}], ], };
Or
//babel.config.cjs module.exports = { presets: [ ["@babel/preset-env", {targets: {esmodules: true, node: "current"}}], ["@babel/preset-react", {runtime: "automatic"}], ], };
NOTE: Renaming babel.config.js to babel.config.cjs to explicitly indicate that it is a CommonJS module.
-
Create config Jest && Setup files
jest.config.ts
export default { collectCoverage: true, coverageDirectory: "coverage", preset: "ts-jest", testEnvironment: "jest-environment-jsdom", // To fix "Cannot find module ‘msw/node’ (JSDOM), set the testEnvironmentOptions.customExportConditions option in your jest.config.js to [''] => https://mswjs.io/docs/migrations/1.x-to-2.x#requestresponsetextencoder-is-not-defined-jest //testEnvironmentOptions: { // customExportConditions: [""], //}, transform: { //Transforms TypeScript files (.ts, .tsx) into JavaScript. "^.+\\.(ts|tsx)$": "ts-jest", // Transforms modern JavaScript (ES6+, JSX) into a format Jest can understand. "^.+\\.(js|jsx|mjs|cjs)$": "babel-jest", // Use babel-jest for JS files }, // This specifies a list of files that should be run after setting up the testing framework but before running the tests. setupFilesAfterEnv: ["<rootDir>/jest.setup.ts"], // To fix R"equest/Response/TextEncoder is not defined (Jest)" // setupFiles: ["<rootDir>/jest.polyfills.ts"], // This configuration tells Jest to use jest-transform-stub for SVG (and other static file) imports. Now, when you import an SVG file in your tests, Jest will replace it with a stub and won't throw an error. moduleNameMapper: { "\\.(css|less|scss|sss|styl)$": "jest-css-modules", "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "jest-transform-stub", }, //"transforming" refers to the process of converting source code into a format that Jest can understand and execute during testing. This is necessary because Jest runs in a Node.js environment, which may not natively support modern JavaScript or TypeScript features, JSX, or other non-standard syntax. //The transformIgnorePatterns configuration in Jest specifies which files should not be transformed before running tests. By default, Jest skips transforming files in node_modules for performance reasons. //If the transformIgnorePatterns array is empty (transformIgnorePatterns: []), Jest will attempt to transform all files, including those in the node_modules directory. This means Jest will apply the specified transformers (like ts-jest or babel-jest) to every file it encounters, regardless of its location. transformIgnorePatterns: [], //Determines which test files Jest skips running entirely. testPathIgnorePatterns: ["/node_modules/", "/dist/", "/.yarn/"], };
jest.setup.ts
//If will install the polyfill Fetch API, to will need to import this package import "whatwg-fetch"; import dotenv from "dotenv"; dotenv.config({path: ".env.test"});
anyfile.test.tsx
//For avoid some mistakes jest DOM syntax in file tests import '@testing-library/jest-dom' . . .
-
Request/Response/TextEncoder is not defined (Jest)
When you execute your script test and if you notice some message error with the above message or something like that, so you have to do the following or follow the steps of the next link requestresponsetextencoder
yarn add jest-fixed-jsdom
and jest.config.ts, we have to replace the value of the property testEnvironment by 'jest-fixed-jsdom'
module.exports = { testEnvironment: 'jest-fixed-jsdom', }
-
Setting up environment variables for testing with jest
For this, we need to install dotenv package
yarn add dotenv
Then we need to set up this package into the file jest.setup.js just created
import dotenv from "dotenv"; dotenv.config({ path: ".env.test" }); jest.mock("./src/constants/environments", () => ({ BACKEND_URL: process.env.BACKEND_URL, PRODUCTS_URL: process.env.PRODUCTS_URL, USERS_URL: process.env.USERS_URL, ORDERS_URL: process.env.ORDERS_URL, PAYPAL_URL: process.env.PAYPAL_URL, }));
-
Setting up MSW (MOCK SERVICE WORKER)
Only you need the following steps or follow the next link msw
yarn add msw --save-dev
src/mocks/handlers.ts
import {delay, http, HttpResponse} from "msw"; import { BACKEND_URL } from "../constants/environments"; export const handlers = [ http.get(`${BACKEND_URL}/api/products`, async () => { await delay(1000); return HttpResponse.json([]); }), http.get(`${BACKEND_URL}/api/products/:slug`, async (req) => { const {slug} = req.params; await delay(1000); return HttpResponse.json({}); }), ];
src/mocks/node.ts
import {setupServer} from "msw/node"; import {handlers} from "./handlers"; export const server = setupServer(...handlers);
jest.setup.ts
import "whatwg-fetch"; import dotenv from "dotenv"; // Load environment variables before mocking dotenv.config({path: ".env.test"}); import {server} from "./src/mocks/node"; import {store} from "./src/mocks/renderWithProviders"; import { api } from "./src/store/services"; // Mock environment constants after dotenv config jest.mock("./src/constants/environments", () => ({ BACKEND_URL: process.env.BACKEND_URL, PRODUCTS_URL: process.env.PRODUCTS_URL, USERS_URL: process.env.USERS_URL, ORDERS_URL: process.env.ORDERS_URL, PAYPAL_URL: process.env.PAYPAL_URL, })); // MSW server lifecycle hooks beforeEach(() => { store.dispatch(api.util.resetApiState()); }); beforeAll(() => server.listen()); afterEach(() => server.resetHandlers()); afterAll(() => server.close());
-
Update the file tsconfig.json for avoid syntax mistakes jest and node not recognized for typescript
{ "compilerOptions": { ... /* Jest */ "jsx": "react-jsx", "esModuleInterop": true, "types": ["jest", "node"], }, // The include property in the tsconfig.json file is used to specify a list of glob patterns for files that should be included in your TypeScript project. "include": ["src"], //OPTIONAL "references": [ { "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" } ] }
NOTE:If you do some changes here, you must restart typescript in the command palette (Ctrl+Shift+P), then restart Typescript Server to apply this changes
-
More info https://mswjs.io/docs/migrations/1.x-to-2.x#requestresponsetextencoder-is-not-defined-jest mswjs/msw#1934
-
Now you are ready to test without problems with typescript
NOTE: Is not neccesary create the file babel.config.js