首页 > 解决方案 > Jest Testing in React Native (EXPO) .jsx extension not working "React.createElement: type is invalid"

问题描述

Issue

I'm trying to test using jest, but it looks like my compiler is not handling .jsx files. If I change both of the files extension to js: (App.jsx and App.test.jsx) to (App.JS and App.test.JS), it does work. But I want to be able to use jsx files.

Files

folder structure

App.jsx

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

export default function App() {
  return (
    <View style={styles.container}>
      <Text>Open up App.js to start working on your app!</Text>
    </View>
  );
}

App.test.jsx

import React from 'react';
// import { render } from '@testing-library/react-native';
import renderer from 'react-test-renderer';

import App from './App';

it('renders correctly', () => {
  const tree = renderer.create(<App />).toJSON();
  expect(tree.children.length).toBe(1);

  // const { toJSON } = render(<App />); // ** THIS DOESN'T WORK EITHER **
  // expect(toJSON()).toMatchSnapshot();
});

Console Error

Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

enter image description here

package.json

{
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "expo start",
    "eject": "expo eject",
    "test": "jest --watch",
    "test:debug": "jest",
    "test:coverage": "npm test -- --coverage --watchAll",
    "test:pr": "npm test -- coverage --ci --silent --changedSince=origin/development --coverageReporters='text' --coverageReporters='lcov'",
    "test:all": "npm test -- --coverage --ci --silent --watchAll=false",
    "linter": "eslint src",
    "linter:fix": "eslint src --fix"
  },
  "dependencies": {
    "@react-native-async-storage/async-storage": "^1.13.0",
    "@react-navigation/native": "^5.9.4",
    "@reduxjs/toolkit": "^1.5.1",
    "babel-jest": "^26.6.3",
    "expo": "~41.0.1",
    "expo-status-bar": "~1.0.4",
    "i18next": "^20.2.2",
    "moment": "^2.29.1",
    "msw": "^0.28.2",
    "node-fetch": "^2.6.1",
    "react": "16.13.1",
    "react-dom": "16.13.1",
    "react-native": "https://github.com/expo/react-native/archive/sdk-41.0.0.tar.gz",
    "react-native-web": "~0.13.12",
    "redux": "^4.1.0",
    "redux-thunk": "^2.3.0"
  },
  "devDependencies": {
    "@babel/core": "^7.9.0",
    "@babel/eslint-parser": "^7.14.2",
    "@babel/eslint-plugin": "^7.13.16",
    "@babel/plugin-proposal-class-properties": "^7.13.0",
    "@testing-library/react-native": "^7.2.0",
    "@types/jest": "^26.0.23",
    "eslint": "^7.26.0",
    "eslint-config-airbnb": "^18.2.1",
    "eslint-plugin-import": "^2.23.0",
    "eslint-plugin-jsx-a11y": "^6.4.1",
    "eslint-plugin-react": "^7.23.2",
    "eslint-plugin-react-hooks": "^4.2.0",
    "identity-obj-proxy": "^3.0.0",
    "jest-expo": "^41.0.0",
    "react-test-renderer": "^17.0.2"
  },
  "jest": {
    "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(js|jsx)$",
    "moduleFileExtensions": [
      "js",
      "json",
      "jsx"
    ],
    "preset": "jest-expo",
    "setupFiles": [
      "./jestSetup.js"
    ],
    "transform": {
      "^.+\\.(js|jsx|mjs)$": "babel-jest"
    },
    "moduleNameMapper": {
      ".+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$": "identity-obj-proxy"
    }
  },
  "private": true
}

标签: react-nativejestjsbabeljsexpobabel-jest

解决方案


您需要配置 Jest 以接受 jsx 扩展。这是在你的 package.json 文件的 jest 部分或你的 jest.config.js 文件中完成的(如果你有两个 Jest 似乎忽略了 package.json 的内容)。

看看这个:https ://levelup.gitconnected.com/setting-up-jest-under-expo-to-work-with-jsx-files-ba35a51bc25a

这对我有用:

$ yarn add --dev babel-jest@latest

然后在 package.json 中:

  "jest": {
    "preset": "jest-expo",
    "transformIgnorePatterns": [
      "node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|react-native-svg)"
    ],
    "transform": {
      "^.+\\.[jt]sx?$": "babel-jest"
    }
  }

推荐阅读