2

I've got an issue with react-testing-library with my React project on TypeScript.

I've been searching on many websites an answer, checking tutorials but I'm really stuck and can't find the answer, changing some configurations on babel.config.js, tsconfig.json and jest.config.js, installing new packages (not sure if I had to install @types for testing-library for example) but I'm not expert with all of this and I'm lost.

I've tried an easy test and it says :

Unexpected token, expected "," (11:47)

       9 | describe('Test SectionTitle', () => {
      10 |   test('renders message', () => {
    > 11 |     const { getByText } = render(<SectionTitle tag="h1">Mon titre</SectionTitle>)
         |                                                ^
      12 | 
      13 |     expect(getByText('Mon titre')).toBeInTheDocument()
      14 |   })

The structure of my project is as belows :

    .
    ├── public                      # Where build files are (shoudn't be this way)
    ├── src                         # Source files (alternatively `lib` or `app`)
    │   ├── assets                  # All images
    │   ├── components              # All the components
    │   │   ├── component.spec.ts   # Test files 
    │   │   ├── component.styled.ts # Style of the component with styled-components 
    │   │   ├── component.tsx       # Component file
    │   │   └── index.ts            # Choose what to export
    │   ├── routes                  # All routes with react-router-dom
    │   ├── screens                 # All screens
    │   │   ├── screen.spec.ts      # Test files 
    │   │   ├── screen.styled.ts    # Style of the screen with styled-components 
    │   │   ├── screen.meta.tsx     # Meta tag of the screen with react-helmet 
    │   │   ├── screen.tsx          # Screen file
    │   │   └── index.ts            # Choose what to export
    │   ├── sitemap                 # Sitemap generator (issue about missing some parameters, changefreq, priority, lastmod etc.)[https://github.com/kuflash/react-router-sitemap/issues/39]
    │   ├── style                   # Helpers, utils, variables CSS, global style etc
    │   ├── index.tsx               # Index file
    │   ├── setupTests.ts           # Packages to be imported for tests
    └── README.md
    └── webpack.config.js           # Config of webpack
    └── babel.config.js             # Config of babel
    └── jest.config.js              # Config of jest
    └── tsconfig.json               # Config for TypeScript like imported paths with '@'
    └── custom.d.ts                 # Adding Custom Type Definitions
    └── .prettierrc                 # Rules for prettier
    └── .prettierignore             # Files to be ignored for prettier
    └── .gitignore                  # Files to be ignored for git
    └── package.json                # List of packages and commands to run with yarn
    └── yarn.lock                   # Packages in the node_modules folder

Here's my package.json dependencies and scripts :

{
  "dependencies": {
    "framer-motion": "^1.11.0",
    "react": "^16.13.1",
    "react-cookie-consent": "^5.0.1",
    "react-dom": "^16.13.1",
    "react-ga": "^3.0.0",
    "react-helmet": "^6.0.0",
    "react-router-dom": "^5.1.2",
    "styled-components": "^5.1.0"
  },
  "scripts": {
    "prebuild": "yarn run sitemap",
    "build": "webpack --mode production",
    "start": "webpack-dev-server --mode development",
    "sitemap": "babel-node src/sitemap/sitemap-builder.js",
    "test": "jest -c jest.config.js --watch"
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "./src/**/*.{ts,tsx}": [
      "prettier --write ."
    ]
  },
  "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/cli": "^7.8.4",
    "@babel/core": "^7.9.6",
    "@babel/node": "^7.10.1",
    "@babel/plugin-transform-typescript": "^7.10.1",
    "@babel/preset-env": "^7.9.6",
    "@babel/preset-react": "^7.10.1",
    "@testing-library/jest-dom": "^5.11.0",
    "@testing-library/react": "^10.4.3",
    "@types/jest": "^26.0.3",
    "@types/node": "^14.0.14",
    "@types/react": "^16.9.0",
    "@types/react-dom": "^16.9.0",
    "@types/react-helmet": "^6.0.0",
    "@types/react-router-dom": "^5.1.5",
    "@types/styled-components": "^5.1.0",
    "@types/testing-library__jest-dom": "^5.9.1",
    "@types/testing-library__react": "^10.2.0",
    "babel-loader": "^8.1.0",
    "css-loader": "^3.5.3",
    "file-loader": "^6.0.0",
    "husky": "^4.2.5",
    "jest": "^26.1.0",
    "lint-staged": "^10.2.2",
    "prettier": "^2.0.5",
    "react-router-sitemap": "^1.2.0",
    "source-map-loader": "^0.2.4",
    "style-loader": "^1.2.1",
    "ts-jest": "^26.1.1",
    "ts-loader": "^7.0.3",
    "tsconfig-paths-webpack-plugin": "^3.2.0",
    "typescript": "~3.7.2",
    "webpack": "^4.43.0",
    "webpack-cli": "^3.3.11",
    "webpack-dev-server": "^3.11.0"
  }
}

Here's my jest.config.js :

module.export = {
  preset: 'ts-jest',
  testEnvironment: 'jsdom',
  transform: {
    "^.+\\.tsx?$": "ts-jest"
  },
  roots: ['<rootDir>/src'],
  testMatch: ['<rootDir>/src/**/>(*.)spec.{ts, tsx}'], // finds test
  moduleFileExtensions: ['ts', 'tsx', 'json', 'node'],
  testPathIgnorePatterns: ['/node_modules/', '/public/'],
  setupFilesAfterEnv: '<rootDir>/src/setupTests.ts'
};

Here is my setupTests.ts :

import '@testing-library/jest-dom/extend-expect'
import '@testing-library/react/cleanup-after-each'

This is my tsconfig.json :

{
  "compilerOptions": {
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "allowSyntheticDefaultImports": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "target": "es5",
    "module": "commonjs",
    "rootDir": "src",
    "outDir": "public",
    "jsx": "react",
    "moduleResolution": "node",
    "strict": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "baseUrl": "src",
    "paths": {
      "@assets/*": [
        "assets/*"
      ],
      "@components/*": [
        "components/*"
      ],
      "@routes/*": [
        "routes/*"
      ],
      "@screens/*": [
        "screens/*"
      ],
      "@style/*": [
        "style/*"
      ]
    }
  },
  "include": [
    "src",
    "custom.d.ts"
  ]
}

This is my babel.config.js :

module.exports = {
  presets: ["@babel/preset-env", "@babel/preset-react"],
  plugins: ["@babel/plugin-transform-typescript"]
};

This is my webpack.config.js :

const path = require("path");
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');

module.exports = {
  resolve: {
    extensions: [".tsx", ".ts", ".js"],
    plugins: [new TsconfigPathsPlugin({ configFile: "./tsconfig.json" })]
  },
  devServer: {
    contentBase: path.join(__dirname, "public"),
    compress: true,
    port: 3000,
    historyApiFallback: true,
    publicPath: '/'
  },
  entry: path.resolve(__dirname, "src", "index.tsx"),
  output: {
    path: path.resolve(__dirname, "public"),
    filename: "bundle.js",
    publicPath: '/'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: ["babel-loader"]
      },
      {
        test: /\.ts(x?)$/,
        exclude: /node_modules/,
        use: [{ loader: "ts-loader" }]
      },
      {
        test: /\.css$/,
        use: [{ loader: "style-loader" }, { loader: "css-loader" }]
      },
      {
        test: /\.(png|svg|jpg|gif)$/i,
        use: ["file-loader"]
      },
      {
        enforce: "pre",
        test: /\.js$/,
        loader: "source-map-loader"
      }
    ]
  }
};

The component SectionTitle.tsx :

import React from 'react'
import SectionTitleWrapper from './SectionTitle.styled'

interface IProps {
  children: JSX.Element[] | JSX.Element | string
  tag: 'h1' | 'h2'
}

const SectionTitle = (props: IProps) => <SectionTitleWrapper as={props.tag}>{props.children}</SectionTitleWrapper>

export default SectionTitle

And the test SectionTitle.spec.tsx :

import React from 'react'
import { render, cleanup } from '@testing-library/react'
import SectionTitle from './SectionTitle'

afterEach(cleanup)

describe('Test SectionTitle', () => {
  test('renders message', () => {
    const { getByText } = render(<SectionTitle tag="h1">Mon titre</SectionTitle>)

    expect(getByText('Mon titre')).toBeInTheDocument()
  })
})

To summarize, the website is working, the build is working too but not the tests :/ Thanks in advance for helping me !

2 Answers 2

4

I've forgotten an 's' in module.exports in my jest config. I've added this in my jest config :

  moduleNameMapper: {
    '^@assets/(.*)$': '<rootDir>/src/assets/$1',
    '^@components/(.*)$': '<rootDir>/src/components/$1',
    '^@routes/(.*)$': '<rootDir>/src/routes/$1',
    '^@screens/(.*)$': '<rootDir>/src/screens/$1',
    '^@style/(.*)$': '<rootDir>/src/style/$1'
  }

And I've upgraded TypeScript to this version : ~3.8.0

Sign up to request clarification or add additional context in comments.

Comments

1

Better to use as following:

interface IProps {
  children: React.ReactNode | React.ReactNode[];
  tag: 'h1' | 'h2';
}

Because:

type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;

UPD: Or, maybe you have to pass children as a first parameter and a wrapper component in the render options, like this:

const { getByText } = render(<>Mon titre</>, {
  wrapper: SectionTitle as React.FunctionComponent,
});

16 Comments

Thanks for the tip ! But it doesn't resolve my error :/
Had to try, because at first look it was a type issue of children property. Have you tried to render without passing children ( in your case simple text ) ?
I've tried even to put a <div /> but it didn't work, I've tried your update but it didn't work too :(
Then to get this resolved, we need to see a codesandbox example of your issue, please make it and post here, so we can check it out and help you asap.
I've created a sandbox but how can I use the console to launch yarn start ? codesandbox.io/s/vigilant-haslett-hl3p2?file=/src/…
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.