0

I'm trying to standup some unit tests for my current project. Project was created with create-react-app, and is exclusively front-end code with no server communication whatsoever (so far). I'm using Typescript, Material UI, and ES6 modules, and would like to run some tests using Jest & the React Testing Library.

Out of the box, my create-react-app application was able to run npm test with no problems. However, with the actual development present, I get this error, which seems to be originating from some portion of Material UI's package:

/node_modules/@mui/material/styles/index.js:3 import { formatMuiErrorMessage as _formatMuiErrorMessage } from "@mui/utils";

SyntaxError: Cannot use import statement outside a module

  1 | import * as React from "react";
> 2 | import { alpha } from "@mui/material/styles/index.js";
      ^^^^^^

Through a variety of different pathways, I can also replace this error with other ones, such as

SyntaxError: /src/App.test.tsx: Support for the experimental syntax 'jsx' isn't currently enabled (6:10):

  4 |
  5 | test('renders learn react link', () => {
> 6 |   render(<App />);
    |          ^
  7 |   const linkElement = screen.getByText(/learn react/i);
  8 |   expect(linkElement).toBeInTheDocument();
  9 | });

I have gone through many of the various different suggestions on StackOverflow, including various combinations of Babel setups (like this one, this one, or this one), as well as places like this. Have also tried things like replacing react-scripts test with jest, introducing jest.config.[js|json], messing with my webpack setup, and other things. Most of these will change the error in some way, but none of them have actually solved my problem.

What did eventually "solve" my problem is Solution #2 from this article, but I don't really understand how it works and it seems a little on the shady side (but perhaps not).

So I am hoping someone here can suggest a comprehensive solution that allows ES6 + Typescript + MUI + Jest + CRA to work. OR potentially Jest is just not the right tool for testing ES6 code, in which case if you have a more modern alternative to suggest, that would be welcome as well.

My package.json:

  "name": "visualizations",
  "version": "0.1.0",
  "private": true,
  "type": "module",
  "dependencies": {
    "@emotion/react": "^11.11.1",
    "@emotion/styled": "^11.11.0",
    "@looker/visualizations": "^1.1.4",
    "@mui/icons-material": "^5.14.3",
    "@mui/material": "^5.14.3",
    "@testing-library/jest-dom": "^5.17.0",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "@types/jest": "^27.5.2",
    "@types/node": "^16.18.39",
    "@types/react": "^18.2.17",
    "@types/react-dom": "^18.2.7",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-scripts": "5.0.1",
    "typescript": "^4.9.5",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "this line of code is based on this article https://dev.to/bytebodger/how-i-fixed-the-unexpected-token-error-in-jest-4o1j": "",
    "test": "react-scripts test --transformIgnorePatterns \"node_modules/(?!visualizations)/\" --env=jsdom",
    "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": {
    "@babel/plugin-proposal-private-property-in-object": "^7.21.11",
    "@babel/preset-env": "^7.22.10",
    "@babel/preset-react": "^7.22.5",
    "@babel/preset-typescript": "^7.22.5",
    "babel-jest": "^29.6.3"
  }
}

And tsconfig.json:

  "compilerOptions": {
    "target": "es6",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "ESNext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": false,
    "jsx": "react-jsx"
  },
  "include": ["src"],
  "exclude": ["node_modules"]
}

EDIT: Per request in the comments, here is the jest.config.js that I tried at one point, although I don't currently have one at all.

module.exports = {
   preset: "ts-jest",
   testEnvironment: "jsdom",
   transform: {
     "^.+\\.(ts|tsx)?$": "ts-jest",
     '^.+\\.(js|jsx)$"': "babel-jest",
   }
};
Jake
  • 862
  • 6
  • 10

0 Answers0