7

I was bootstrapping my first TypeScript + React project from scratch. I was successful with the TypeScript and component rendering. However, as I try to add a test, it just fails with some type errors.

I've tried to play around with different configurations, even adding a setupTests.ts file.

Here is my configuration: package.json

{
  ....
      "dependencies": {
        "@babel/plugin-proposal-object-rest-spread": "^7.4.0",
        "@babel/plugin-syntax-dynamic-import": "^7.2.0",
        "@babel/polyfill": "^7.4.0",
        "@babel/preset-env": "^7.4.2",
        "@babel/preset-react": "^7.0.0",
        "@babel/preset-typescript": "^7.3.3",
        "@types/html-webpack-plugin": "^3.2.0",
        "@types/jest": "^24.0.11",
        "@types/react": "^16.8.10",
        "@types/react-dom": "^16.8.3",
        "@types/react-redux": "^7.0.6",
        "@types/react-router-dom": "^4.3.1",
        "@types/redux": "^3.6.0",
        "@types/redux-logger": "^3.0.7",
        "@types/redux-promise": "^0.5.28",
        "@types/webpack": "^4.4.26",
        "@typescript-eslint/eslint-plugin": "^1.5.0",
        "@typescript-eslint/parser": "^1.5.0",
        "babel-jest": "^24.5.0",
        "babel-loader": "^8.0.5",
        "babel-plugin-transform-class-properties": "^6.24.1",
        "babel-preset-es2015": "^6.24.1",
        "babel-preset-react": "^6.24.1",
        "eslint": "^5.16.0",
        "eslint-config-prettier": "^4.1.0",
        "eslint-plugin-prettier": "^3.0.1",
        "eslint-plugin-react-hooks": "^1.6.0",
        "html-webpack-plugin": "^3.2.0",
        "jest": "^24.5.0",
        "jest-dom": "^3.1.3",
        "prettier": "^1.16.4",
        "react": "^16.8.6",
        "react-dom": "^16.8.6",
        "react-redux": "^6.0.1",
        "react-router": "^5.0.0",
        "react-router-dom": "^5.0.0",
        "react-testing-library": "^6.0.3",
        "redux": "^4.0.1",
        "redux-logger": "^3.0.6",
        "redux-promise": "^0.6.0",
        "redux-thunk": "^2.3.0",
        "styled-components": "^4.2.0",
        "ts-loader": "^5.3.3",
        "ts-node": "^8.0.3",
        "webpack": "^4.29.6",
        "webpack-dev-middleware": "^3.6.1",
        "webpack-dev-server": "^3.2.1",
        "webpack-hot-middleware": "^2.24.3"
    },
    "devDependencies": {
        "@babel/core": "^7.4.0",
        "awesome-typescript-loader": "^5.2.1",
        "jest-environment-jsdom": "^24.5.0",
        "source-map-loader": "^0.2.4",
        "ts-jest": "^24.0.1",
        "typescript": "^3.4.1",
        "webpack-cli": "^3.3.0"
    }

.babelrc

{
    "presets": [
        "@babel/react",
        "@babel/typescript",
        [
            "@babel/preset-env",
            {
                "targets": {
                    "browsers": [">0.25%"]
                },
                "modules": false,
                "useBuiltIns": "usage"
            }
        ]
    ],
    "plugins": ["@babel/proposal-class-properties", "@babel/proposal-object-rest-spread"]
}

jest.config.js

module.exports = {
    roots: ['<rootDir>/src'],
    transform: {
      '.*.tsx?$': 'ts-jest',
    },
    testMatch: ['<rootDir>/src/**/?(*.)test.{ts,tsx}'],
    moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
    setupFilesAfterEnv: [
        'react-testing-library/cleanup-after-each', 'jest-dom/extend-expect']
  };

webpack.config.js:

const path = require('path');

// Plugins
const path = require('path')

// Plugins
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    entry: {
        dev: './src/index.tsx',
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'js/[name].bundle.js',
    },
    devServer: {
        compress: true,
        port: 3000,
        hot: true,
    },
    devtool: 'source-map',
    resolve: {
        extensions: ['.ts', '.tsx', '.js', '.jsx'],
    },
    module: {
        rules: [
            /**
             * Gets all .ts, .tsx, or .js files and runs them through eslint
             * and then transpiles them via babel.
             */
            {
                test: /(\.js$|\.tsx?$)/,
                exclude: /(node_modules|bower_components)/,
                use: ['babel-loader'],
            },

            /**
             * All output '.js' files will have any sourcemaps re-processed by
             * source-map-loader.
             */
            { test: /\.js$/, enforce: 'pre', loader: 'source-map-loader' },
        ],
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './public/index.html',
        }),
    ],
}

Very basic component to start with:

import React, {SFC} from 'react'

export const Home: SFC<any> = () => <div>HomePage</div>


export default Home

Right when I even try to pass my component as an argument to the render method I get an error

import { Home } from '../pages'; // this import works
import { render } from 'react-testing-library';

describe('', () => {
    test('should render app', () => {
        render(<Home />) // says it cant find "Home"
    });
});

When I run my test I get this from the console:

  ● Test suite failed to run

    TypeScript diagnostics (customize using `[jest-config].globals.ts-jest.diagnostics` option):
    src/__tests__/App.test.ts:6:27 - error TS1005: '>' expected.

    6         console.log(<Home />);
                                ~
    src/__tests__/App.test.ts:6:28 - error TS1161: Unterminated regular expression literal.

    6         console.log(<Home />);

    src/__tests__/App.test.ts:7:5 - error TS1005: ',' expected.

    7     });
          ~
    src/__tests__/App.test.ts:6:22 - error TS2749: 'Home' refers to a value, but is being used as a type here.

    6         console.log(<Home />);
                           ~~~~

UPDATE: currently my file is called App.test.ts

if I change it to App.test.tsx and add import * as React from 'react' to the test the errors go away but the test fails with this error:

  ● Test suite failed to run

    Jest encountered an unexpected token

    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

    Here's what you can do:
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    /<user>/code/react-leader-board/src/__tests__/App.test.tsx:15
            react_testing_library_1.render(<pages_1.Home />);
                                           ^

    SyntaxError: Unexpected token <

      at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:451:17)
      at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:493:19)
13
  • should it be @babel/preset-react and not @babel/react? Commented Mar 30, 2019 at 21:31
  • 1
    what happens now if you remove the awesome-typescript-loader from modules.rules in your webpack config? this error now means that babel is not processing your files correctly. my thought is that the awesome-typescript-loader is being run instead of babel since it's first in the list of rules. Commented Mar 31, 2019 at 10:04
  • 1
    are you able to make a reproducable repo? here is my jest.config.js: hastebin.com/acopakehoy.js here is my tsconfig.json: hastebin.com/rahorugeri.js and i use this across many projects without an issue Commented Mar 31, 2019 at 15:12
  • 1
    try this: hastebin.com/turohahefu.json (setting modules to true instead of commonjs was a legacy syntax, i just recommended it incase it didn't work. Commented Apr 1, 2019 at 7:14
  • 1
    @bitten that worked!!!! You are the best thanks. Please add babelrc config as answer and I will give accepted answer :) Commented Apr 2, 2019 at 15:18

2 Answers 2

40

I ran into the same issue, the problem was the extension of a file, it should be .tsx, for example MyComponent.test.tsx

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

Comments

2

I would suggest making sure that your modules are being compiled in the test settings of your env preset:

{
    "presets": [
        "@babel/react",
        "@babel/typescript",
        [
            "@babel/preset-env",
            {
                "targets": {
                    "browsers": [">0.25%"]
                },
                "modules": false,
                "useBuiltIns": "usage"
            }
        ]
    ],
    "plugins": ["@babel/proposal-class-properties", "@babel/proposal-object-rest-spread"],
    "env": {
        "test": {
            "presets": [
                ["@babel/preset-env", {
                    "modules": "commonjs"
                }]
            ]
        }
    }
}

and using babel-jest:

transform: { '\\.(ts|tsx)?$': 'babel-jest',`

Comments

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.