Search code examples
typescriptjestjsenzymecreate-react-app

Jest fails to run .tsx files (CRA 2, enzyme)


I am unable to use 'npm test' in my ts CRA 2 project, because jest fails at handling .tsx. I followed this [set-up guide] (https://thetrevorharmon.com/blog/configuring-jest-and-enzyme-in-create-react-app-on-typescript).

I'm trying t use ts-jest to transform .tsx files but it doesn't work.

I found that changing the "jsx" option in the tsconfig.json to "react" from "preserve" will allow jest to run without errors. This, unfortunately, is incompatible the the "npm run" script packaged with CRA 2, as it will revert the jsx type back to "preserve".

jest config:

module.exports = {
  roots: ['<rootDir>/src'],
  transform: {
    '^.+\\.tsx?$': 'ts-jest',
  },
  testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$',
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
};

test file:

import React from 'react';
import { shallow } from 'enzyme';
import AboutPage from 'pages/AboutPage';

describe('MyComponent', () => {
  it('should render correctly with no props', () => {
    const component = shallow(<AboutPage />);

    expect(component).toMatchSnapshot();
  });
});

tsconfig

{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "preserve",
    "baseUrl": "./src"
  },
  "include": [
    "src"
  ]
}

All tests should pass but instead the following Jest error message results:

 FAIL  src/__tests__/AboutPage.test.tsx
  ● 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 p
lain JavaScript.


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

    Here's what you can do:
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgn
orePatterns" 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 wit
h 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:

    /Users/josh/Repos/welfare-react-capacitor/src/__tests__/AboutPage.test.tsx:11
            var component = enzyme_1.shallow(<AboutPage_1.default />);
                                             ^

    SyntaxError: Unexpected token <

      at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransf
ormer.js:471:17)
      at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:513:25
)

After adding babel-jest:

    SyntaxError: /Users/josh/Repos/welfare-react-capacitor/src/__tests__/AboutPage.test.tsx: Unexpec
ted token (7:30)

       5 | describe('MyComponent', () => {

       6 |   it('should render correctly with no props', () => {
    >  7 |     const component = shallow(<AboutPage />);
         |                               ^
       8 |
       9 |     expect(component).toMatchSnapshot();
      10 |   });

      at Parser.raise (node_modules/@babel/core/node_modules/@babel/parser/lib/index.js:6344:17)
      at Parser.unexpected (node_modules/@babel/core/node_modules/@babel/parser/lib/index.js:7659:16
)
      at Parser.parseExprAtom (node_modules/@babel/core/node_modules/@babel/parser/lib/index.js:8828
:20)
      at Parser.parseExprSubscripts (node_modules/@babel/core/node_modules/@babel/parser/lib/index.j
s:8413:23)
      at Parser.parseMaybeUnary (node_modules/@babel/core/node_modules/@babel/parser/lib/index.js:83
93:21)
      at Parser.parseExprOps (node_modules/@babel/core/node_modules/@babel/parser/lib/index.js:8280:
23)
      at Parser.parseMaybeConditional (node_modules/@babel/core/node_modules/@babel/parser/lib/index
.js:8253:23)
      at Parser.parseMaybeAssign (node_modules/@babel/core/node_modules/@babel/parser/lib/index.js:8
200:21)
      at Parser.parseExprListItem (node_modules/@babel/core/node_modules/@babel/parser/lib/index.js:
9475:18)
      at Parser.parseCallExpressionArguments (node_modules/@babel/core/node_modules/@babel/parser/li
b/index.js:8620:22)

Solution

  • Looks like you are missing the babel-loader plugin.