9

I'm getting the following error when running the following test file:

// TestComp.test.tsx
import React from "react";
import { TextInput, View } from "react-native";

import { render, fireEvent } from "@testing-library/react-native";

const TestComp = () => {
  return (
    <View>
      <TextInput testID="test-input" onChangeText={(txt) => console.log(txt)}></TextInput>
    </View>
  );
};

describe("Testcomp", () => {
  afterEach(() => {
    jest.clearAllMocks();
  });

  test("test me", async () => {
    const { getByTestId } = render(<TestComp />);
    const testInput = getByTestId("test-input");
    fireEvent.changeText(testInput, "hello");
  });
});

Error when running yarn jest:

    Details:

    /mnt/ubuntu/home/richardwu/code/topspin/src/components/TestComp.test.tsx:46
        return (<react_native_1.View>
                ^

    SyntaxError: Unexpected token '<'

      at compileFunction (node:vm:355:18)

The error disappears if I change the file to jsx. The issue is the components I will be importing will be in tsx files, so ideally I want jest to be able to run with tsx files.

I've followed the instructions for setting up typescript with jest, where I have the following config files:

// jest.config.js
module.exports = {
  preset: "react-native",
  transform: {
    "^.+\\.tsx?$": "ts-jest",
    "^.+\\.jsx?$": "babel-jest",
  },
  transformIgnorePatterns: ["node_modules/?!(react-icons)"],
  setupFilesAfterEnv: ["<rootDir>/src/setupTests.ts"],
};
// babel.config.js
module.exports = function (api) {
  api.cache(true);
  return {
    presets: ["babel-preset-expo", "@babel/preset-typescript"],
  };
};
// package.json
{
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web",
    "eject": "expo eject",
    "test": "jest"
  },
  "dependencies": {
    "@apollo/client": "^3.2.5",
    "@expo-google-fonts/inter": "^0.1.0",
    "@react-native-community/masked-view": "0.1.10",
    "@types/jest": "^26.0.19",
    "@types/react-router-native": "^5.1.0",
    "expo": "~39.0.2",
    "expo-auth-session": "~2.0.0",
    "expo-constants": "~9.2.0",
    "expo-facebook": "~9.0.0",
    "expo-font": "~8.3.0",
    "expo-status-bar": "~1.0.2",
    "firebase": "^8.0.0",
    "graphql": "^15.4.0",
    "native-base": "^2.13.14",
    "react": "16.13.1",
    "react-dom": "16.13.1",
    "react-hook-form": "^6.11.0",
    "react-native": "https://github.com/expo/react-native/archive/sdk-39.0.4.tar.gz",
    "react-native-deck-swiper": "^2.0.5",
    "react-native-elements": "^3.0.0-alpha.1",
    "react-native-expo-viewport-units": "^0.0.8",
    "react-native-fbsdk": "^2.0.0",
    "react-native-gesture-handler": "~1.7.0",
    "react-native-reanimated": "~1.13.0",
    "react-native-safe-area-context": "3.1.4",
    "react-native-screens": "~2.10.1",
    "react-native-swipe-cards": "^0.1.1",
    "react-native-web": "~0.13.12",
    "react-router-native": "^5.2.0",
    "react-tinder-card": "^1.3.1",
    "ts-jest": "^26.4.4"
  },
  "devDependencies": {
    "@babel/core": "^7.12.10",
    "@babel/preset-env": "^7.12.11",
    "@babel/preset-typescript": "^7.12.7",
    "@testing-library/jest-dom": "^5.11.5",
    "@testing-library/react-native": "^7.1.0",
    "@types/react": "^16.9.56",
    "@types/react-dom": "^16.9.9",
    "@types/react-native": "^0.63.34",
    "@types/react-test-renderer": "^17.0.0",
    "babel-jest": "^26.6.3",
    "eslint": "^7.13.0",
    "eslint-plugin-jest": "^24.1.3",
    "jest-expo": "^39.0.0",
    "react-test-renderer": "^17.0.1",
    "typescript": "^4.0.5"
  },
  "private": true,
  "jest": {
    "preset": "jest-expo",
    "transformIgnorePatterns": [
      "node_modules/(?!(jest-)?react-native|react-clone-referenced-element|@react-native-community|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|@sentry/.*)"
    ]
  }
}

6
  • 1
    With your current setup, jest will use the config from your package.json. To have it point to your jest.config.js file you can update the test script to jest --config <insert_path_to_jest.config.js>. Commented Dec 27, 2020 at 17:38
  • 1
    I just tried running it with the --config flag: doesn't seem like it fixes the issue though. Commented Dec 28, 2020 at 3:55
  • 1
    try adding ts-loader or awesome-ts-loader Commented Dec 29, 2020 at 17:28
  • 2
    Have you tried using babel-jest for both JSX and TSX files? It looks like you have @babel/preset-typescript installed so that should work. Commented Jan 4, 2021 at 12:46
  • 1
    @MarkSkelton Modfiying the tsx? transform in my jest.config.js to babel-jest worked! Feel free to write up the answer and I'll mark it resolved. Commented Jan 5, 2021 at 18:26

2 Answers 2

6
+50

Since you are already using Babel and @babel/preset-typescript, you can update your Jest config to use babel-jest for both JavaScript and TypeScript files. Simply update your transform regex to the following.

// jest.config.js
module.exports = {
  preset: "react-native",
  transform: {
    "^.+\\.[jt]sx?$": "babel-jest",
  },
  transformIgnorePatterns: ["node_modules/?!(react-icons)"],
  setupFilesAfterEnv: ["<rootDir>/src/setupTests.ts"],
};

With that change, you can then uninstall ts-jest from your project since it will no longer be used.

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

Comments

0

What helped in my case was installing ts-jest with npm i -D ts-jest and configuring like this:

// jest.config.js
const {defaults: tsjPreset} = require('ts-jest/presets');
module.exports = {
  ...tsjPreset,
  preset: 'react-native',
  transform: {
    '^.+\\.jsx$': 'babel-jest',
    '^.+\\.tsx?$': [
      'ts-jest',
      {
        tsconfig: 'tsconfig.spec.json',
      },
    ],
  },
  transformIgnorePatterns: [
    'node_modules/(?!(@react-native|react-native|react-native-vector-icons|react-native-config|@react-native-async-storage)/)',
  ],
}


// tsconfig.spec.json
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "jsx": "react"
  }
}

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.